crossroads

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

commit 5fbb190726d27fc0550fd2aa4a63fa0cc41dbd28
parent 1869b862162fc85e367a7c3bfa05e57c54fcac60
Author: finwo <finwo@pm.me>
Date:   Sat,  3 Jan 2026 19:31:47 +0100

1.45

Diffstat:
MChangeLog | 13+++++++++++++
MMakefile | 4++++
Mdoc/Makefile | 1+
Mdoc/crossroads.1 | 9+++++++--
Mdoc/crossroads.conf.7 | 54++++++++++++++++++++++++++++++++++++++++++++++++------
Mdoc/crossroads.html | 2390++++++++++++++++++++++++++++++++++++++++++-------------------------------------
Mdoc/crossroads.pdf | 0
Adoc/main/conf/headerinspection.yo | 13+++++++++++++
Mdoc/main/conf/shmkey.yo | 4++--
Mdoc/main/config.yo | 23++++++++++++++++++++++-
Mdoc/main/tips.yo | 13++++++++-----
Mdoc/main/tips/clientip.yo | 3+++
Adoc/main/tips/deeporshallow.yo | 103+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mdoc/main/tips/externalhandler.yo | 29++++++++++++++---------------
Mdoc/main/tips/httpstickiness.yo | 6+++++-
Mdoc/man/crossroads.yo | 10+++++++---
Metc/Makefile.conf | 7+++++--
Metc/Makefile.def | 15+++++++++++----
Metc/Makefile.help | 6++++--
Metc/svnrev.txt | 2+-
Msrc/Makefile | 7+++++++
Msrc/crossroads-daemon/Makefile | 3+++
Msrc/crossroads-daemon/main.c | 2+-
Msrc/crossroads.h | 15++++++++++++++-
Msrc/crossroads/Makefile | 4+++-
Msrc/crossroads/main.c | 2+-
Msrc/lib/Makefile | 1+
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 | 9+++++----
Msrc/lib/createcommandlinespace.c | 2+-
Msrc/lib/data.c | 3++-
Msrc/lib/deallocreporter.c | 2+-
Msrc/lib/decrclientcount.c | 2+-
Msrc/lib/dns.c | 2+-
Msrc/lib/error.c | 2+-
Msrc/lib/forktcpservicer.c | 14+++++++-------
Msrc/lib/hashpjw.c | 2+-
Msrc/lib/httpcopy.c | 6+++---
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 | 39++++++++++++++++-----------------------
Msrc/lib/httpserversocket.c | 19+++++++++----------
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 | 792+++++++++++++++++++++++++++++++++++++++++--------------------------------------
Msrc/lib/lexer.l | 15+++++++++++++++
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 | 8++++----
Msrc/lib/netcopy.c | 2+-
Msrc/lib/netread.c | 2+-
Msrc/lib/netwrite.c | 2+-
Msrc/lib/parser.c | 809++++++++++++++++++++++++++++++++++++++++++-------------------------------------
Msrc/lib/parser.h | 3+++
Msrc/lib/parser.y | 42++++++++++++++++++++++++++++++++++++++++--
Msrc/lib/parserclose.c | 2+-
Msrc/lib/parserfilename.c | 2+-
Msrc/lib/parserinput.c | 2+-
Msrc/lib/parseropen.c | 8++++----
Msrc/lib/parserrun.c | 2+-
Msrc/lib/parserskipchar.c | 2+-
Msrc/lib/parserskipline.c | 2+-
Msrc/lib/restart.c | 2+-
Msrc/lib/runservice.c | 4++--
Msrc/lib/serve.c | 2+-
Asrc/lib/setproctitle.c | 59+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Dsrc/lib/setprogramtitle.c | 42------------------------------------------
Msrc/lib/showconfig.c | 26+++++++++++++++-----------
Msrc/lib/showservices.c | 2+-
Msrc/lib/showstatus.c | 2+-
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 | 5+++--
Msrc/lib/tellservice.c | 2+-
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 | 4+++-
Msrc/lib/usage.txt | 7++++---
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++++-
Mtools/c-conf | 5++++-
144 files changed, 2717 insertions(+), 2136 deletions(-)

diff --git a/ChangeLog b/ChangeLog @@ -1,6 +1,19 @@ ChangeLog for Crossroads ------------------------------------------------------------------------------ +1.45 [KK 2007-06-12] + - Configuration option 'headerinspection {deep|shallow}' + implemented. Documentation updated. Several other documentation fixes. + - New make target 'dbginstall', installs gdb-able versions into + /usr/local/bin + - Upped c-conf to 1.09: /usr/lib64 is in the library search path + (thanks Joern F. for pointing this one out). + - Added setproctitle() for non-BSD-ish systems. Previous + set_program_title() is obsolete (it woundn't save the envp). + - Flag -B <bufsize> introduced, making the TCP buffer size + variable. Previous constant TCP_BUFSZ is now DEFAULT_TCP_BUFSZ, + which is now 5k instead of 10k. + 1.44 [KK 2007-06-12] - Small bugfix in -b flag handling (useful during debugging only). diff --git a/Makefile b/Makefile @@ -15,6 +15,10 @@ install: local BASE=$(BASE) $(MAKE) -C src install BASE=$(BASE) $(MAKE) -C doc install +dbginstall: local + BASE=$(BASE) $(MAKE) -C src dbginstall + BASE=$(BASE) $(MAKE) -C doc dbginstall + documentation: BASE=$(BASE) $(MAKE) -C doc diff --git a/doc/Makefile b/doc/Makefile @@ -25,6 +25,7 @@ defs: echo 'redef(MAINTAINEREMAIL)(1)($(MAINTAINEREMAIL))' \ >> crossroads-defs.yo +dbginstall: install install: $(BASE)/tools/installdoc $(PREFIX) crossroads.1 crossroads.conf.7 diff --git a/doc/crossroads.1 b/doc/crossroads.1 @@ -56,6 +56,12 @@ Crossroads recognizes the following flags: configuration to \fIstdout\fP\&. For debugging only\&. .IP .IP o +\fB-B\fP \fIsize\fP: Sets the size of network buffers\&. Larger +buffers will mean a less number of \f(CWread()\fP or +\f(CWwrite()\fP operations, but a larger memory +footprint\&. Usually the default value will do fine\&. +.IP +.IP o \fB-C\fP: Writes the compile time configuration to \fIstdout\fP and stops\&. Useful when submitting bug reports\&. .IP @@ -131,4 +137,4 @@ under which it occurs\&. .IP o Author: Karel Kubat .IP o - Maintainer: Karel Kubat karel@kubat\&.nl -\ No newline at end of file + Maintainer: Karel Kubat karel@kubat\&.nl diff --git a/doc/crossroads.conf.7 b/doc/crossroads.conf.7 @@ -67,6 +67,28 @@ service web { .PP The \f(CWport\fP statement is then read as \f(CWport 80\fP\&. .PP +The statement \f(CW#define\fP can also be very nicely used when trying out +Crossroads configurations\&. Crossroads has a statement \f(CWverbosity\fP +\f(CWtrue\fP that causes debugging information to be logged\&. Once a +configuration has proven to work, you\&'ll most likely want +\f(CWverbosity\fP \f(CWfalse\fP so that overhead due to logging is +avoided\&. This can be easily implemented using \f(CW#define\fP: +.PP +.nf +/* Set DEBUG to true or false; + * true is for testing purposes, + * false is for production */ +#define DEBUG true + +service web { + verbosity DEBUG; + \&. + \&. /* More statements follow here */ + \&. +} +.fi + +.PP \fBKeywords, numbers, identifiers, generic strings\fP .PP In a configuration file, statements are identified by \fIkeywords\fP, @@ -127,6 +149,17 @@ 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 +\fBport - Specifying the listen port\fP +.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 \fBtype - Defining the service type\fP .IP "Description:" The \f(CWtype\fP statement defines how crossroads handles the stated @@ -148,15 +181,22 @@ default), even for HTTP protocols\&. \f(CWany\fP .PP -\fBport - Specifying the listen port\fP +\fBheaderinspection - are all HTTP headers inspected\fP .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\&. +The \f(CWheaderinspection\fP directive defines whether Crossroads +must inspect all HTTP headers that are seen on one TCP connection, or +only the first ones\&. There are two possible values for this directive: +\f(CWdeep\fP and \f(CWshallow\fP\&. In \f(CWdeep\fP mode, all information that is +seen on the TCP link is monitored +and parsed, and all HTTP header blocks are analyzed and subject to +directives such as \f(CWaddclientheader\fP\&. In \f(CWshallow\fP mode, only the +first header block that the server sends, and the first header block +that forms the server\&'s answer, are analyzed\&. .IP "Syntax:" -\f(CWport\fP \fInumber\fP +\f(CWheaderinspection\fP \fIspecifier\fP, where \fIspecifier\fP is +\f(CWdeep\fP or \f(CWshallow\fP .IP "Default:" -There is no default\&. This is a required setting\&. +\f(CWdeep\fP .PP \fBbindto - Binding to a specific IP address\fP @@ -366,6 +406,8 @@ and as long as each invocation of crossroads uses it\&. .IP "Default:" 0, which means that crossroads will \&'guess\&' its own key, based on the service name\&. + +.PP \fBallow* and deny* - Allowing or denying connections\fP .IP "Description:" Crossroads can allow or deny 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.44</title> +<title>Crossroads 1.45</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.44</h1> +<h1>Crossroads 1.45</h1> <h2>Karel Kubat <br> Maintained by Karel Kubat (karel@kubat.nl)</h2> @@ -58,99 +58,101 @@ </dl> <dt><a href="#l22">4.2: Service definitions</a></dt> <dl> -<dt><a href="#l23">4.2.1: type - Defining the service type</a></dt> -<dt><a href="#l24">4.2.2: port - Specifying the listen port</a></dt> -<dt><a href="#l25">4.2.3: bindto - Binding to a specific IP address</a></dt> -<dt><a href="#l26">4.2.4: verbosity - Controlling debug output</a></dt> -<dt><a href="#l27">4.2.5: dispatchmode - How are back ends selected</a></dt> -<dt><a href="#l28">4.2.6: revivinginterval - Back end wakeup calls</a></dt> -<dt><a href="#l29">4.2.7: maxconnections - Limiting concurrent clients at service level</a></dt> -<dt><a href="#l30">4.2.8: backlog - The TCP Back Log size</a></dt> -<dt><a href="#l31">4.2.9: shmkey - Shared Memory Access</a></dt> -<dt><a href="#l32">4.2.10: allow* and deny* - Allowing or denying connections</a></dt> -<dt><a href="#l33">4.2.11: useraccount - Limiting the effective ID of external processes</a></dt> +<dt><a href="#l23">4.2.1: port - Specifying the listen port</a></dt> +<dt><a href="#l24">4.2.2: type - Defining the service type</a></dt> +<dt><a href="#l25">4.2.3: headerinspection - are all HTTP headers inspected</a></dt> +<dt><a href="#l26">4.2.4: bindto - Binding to a specific IP address</a></dt> +<dt><a href="#l27">4.2.5: verbosity - Controlling debug output</a></dt> +<dt><a href="#l28">4.2.6: dispatchmode - How are back ends selected</a></dt> +<dt><a href="#l29">4.2.7: revivinginterval - Back end wakeup calls</a></dt> +<dt><a href="#l30">4.2.8: maxconnections - Limiting concurrent clients at service level</a></dt> +<dt><a href="#l31">4.2.9: backlog - The TCP Back Log size</a></dt> +<dt><a href="#l32">4.2.10: shmkey - Shared Memory Access</a></dt> +<dt><a href="#l33">4.2.11: allow* and deny* - Allowing or denying connections</a></dt> +<dt><a href="#l34">4.2.12: useraccount - Limiting the effective ID of external processes</a></dt> </dl> -<dt><a href="#l34">4.3: Backend definitions</a></dt> +<dt><a href="#l35">4.3: Backend definitions</a></dt> <dl> -<dt><a href="#l35">4.3.1: server - Specifying the back end address</a></dt> -<dt><a href="#l36">4.3.2: verbosity - Controlling verbosity at the back end level</a></dt> -<dt><a href="#l37">4.3.3: retries - Specifying allowed failures</a></dt> -<dt><a href="#l38">4.3.4: weight - When a back end is more equal than others</a></dt> -<dt><a href="#l39">4.3.5: decay - Levelling out activity of a back end</a></dt> -<dt><a href="#l40">4.3.6: onstart, onend, onfail - Action Hooks</a></dt> -<dt><a href="#l41">4.3.7: trafficlog and throughputlog - Debugging and Performance Aids</a></dt> -<dt><a href="#l42">4.3.8: stickycookie - Back end selection with an HTTP cookie</a></dt> -<dt><a href="#l43">4.3.9: HTTP Header Modification Directives</a></dt> +<dt><a href="#l36">4.3.1: server - Specifying the back end address</a></dt> +<dt><a href="#l37">4.3.2: verbosity - Controlling verbosity at the back end level</a></dt> +<dt><a href="#l38">4.3.3: retries - Specifying allowed failures</a></dt> +<dt><a href="#l39">4.3.4: weight - When a back end is more equal than others</a></dt> +<dt><a href="#l40">4.3.5: decay - Levelling out activity of a back end</a></dt> +<dt><a href="#l41">4.3.6: onstart, onend, onfail - Action Hooks</a></dt> +<dt><a href="#l42">4.3.7: trafficlog and throughputlog - Debugging and Performance Aids</a></dt> +<dt><a href="#l43">4.3.8: stickycookie - Back end selection with an HTTP cookie</a></dt> +<dt><a href="#l44">4.3.9: HTTP Header Modification Directives</a></dt> </dl> </dl> -<dt><h3><a href="#l44">5: Tips, Tricks and Random Remarks</a></h3></dt> +<dt><h3><a href="#l45">5: Tips, Tricks and Random Remarks</a></h3></dt> <dl> -<dt><a href="#l45">5.1: How back ends are selected in load balancing</a></dt> +<dt><a href="#l46">5.1: Configuration examples</a></dt> <dl> -<dt><a href="#l46">5.1.1: Bysize, byduration or byconnections?</a></dt> -<dt><a href="#l47">5.1.2: Averaging size and duration</a></dt> -<dt><a href="#l48">5.1.3: Specifying decays</a></dt> -<dt><a href="#l49">5.1.4: Adjusting the weights</a></dt> +<dt><a href="#l47">5.1.1: A load balancer for three webserver back ends</a></dt> +<dt><a href="#l48">5.1.2: An HTTP forwarder when travelling</a></dt> +<dt><a href="#l49">5.1.3: SSH login with enforced idle logout</a></dt> </dl> -<dt><a href="#l50">5.2: Throttling the number of concurrent connections</a></dt> -<dt><a href="#l51">5.3: Using an external program to dispatch</a></dt> +<dt><a href="#l50">5.2: How back ends are selected in load balancing</a></dt> <dl> -<dt><a href="#l52">5.3.1: Configuring the external handler</a></dt> -<dt><a href="#l53">5.3.2: Writing the external handler</a></dt> -<dt><a href="#l54">5.3.3: Examples of external handlers</a></dt> +<dt><a href="#l51">5.2.1: Bysize, byduration or byconnections?</a></dt> +<dt><a href="#l52">5.2.2: Averaging size and duration</a></dt> +<dt><a href="#l53">5.2.3: Specifying decays</a></dt> +<dt><a href="#l54">5.2.4: Adjusting the weights</a></dt> </dl> -<dt><a href="#l55">5.4: TCP Session Stickiness</a></dt> -<dt><a href="#l56">5.5: HTTP Session Stickiness</a></dt> +<dt><a href="#l55">5.3: Throttling the number of concurrent connections</a></dt> +<dt><a href="#l56">5.4: TCP Session Stickiness</a></dt> +<dt><a href="#l57">5.5: HTTP Session Stickiness</a></dt> <dl> -<dt><a href="#l57">5.5.1: Don't use stickiness!</a></dt> -<dt><a href="#l58">5.5.2: But if you must..</a></dt> +<dt><a href="#l58">5.5.1: Don't use stickiness!</a></dt> +<dt><a href="#l59">5.5.2: But if you must..</a></dt> </dl> -<dt><a href="#l59">5.6: Passing the client's IP address</a></dt> +<dt><a href="#l60">5.6: Passing the client's IP address</a></dt> <dl> -<dt><a href="#l60">5.6.1: Sample Crossroads configuration</a></dt> -<dt><a href="#l61">5.6.2: Sample Apache configuration</a></dt> +<dt><a href="#l61">5.6.1: Sample Crossroads configuration</a></dt> +<dt><a href="#l62">5.6.2: Sample Apache configuration</a></dt> </dl> -<dt><a href="#l62">5.7: Debugging network traffic</a></dt> -<dt><a href="#l63">5.8: IP filtering: Limiting Access by Client IP Address</a></dt> +<dt><a href="#l63">5.7: Deep or shallow HTTP header inspection</a></dt> +<dt><a href="#l64">5.8: Debugging network traffic</a></dt> +<dt><a href="#l65">5.9: IP filtering: Limiting Access by Client IP Address</a></dt> <dl> -<dt><a href="#l64">5.8.1: General Examples</a></dt> -<dt><a href="#l65">5.8.2: Using External Files</a></dt> -<dt><a href="#l66">5.8.3: Mixing Directives</a></dt> +<dt><a href="#l66">5.9.1: General Examples</a></dt> +<dt><a href="#l67">5.9.2: Using External Files</a></dt> +<dt><a href="#l68">5.9.3: Mixing Directives</a></dt> </dl> -<dt><a href="#l67">5.9: Configuration examples</a></dt> +<dt><a href="#l69">5.10: Using an external program to dispatch</a></dt> <dl> -<dt><a href="#l68">5.9.1: A load balancer for three webserver back ends</a></dt> -<dt><a href="#l69">5.9.2: An HTTP forwarder when travelling</a></dt> -<dt><a href="#l70">5.9.3: SSH login with enforced idle logout</a></dt> +<dt><a href="#l70">5.10.1: Configuring the external handler</a></dt> +<dt><a href="#l71">5.10.2: Writing the external handler</a></dt> +<dt><a href="#l72">5.10.3: Examples of external handlers</a></dt> </dl> -<dt><a href="#l71">5.10: Linux and ip_conntrack_max</a></dt> -<dt><a href="#l72">5.11: Marking back ends as bad after more than one try</a></dt> -<dt><a href="#l73">5.12: Scripting Crossroads' back end availability</a></dt> -<dt><a href="#l74">5.13: Rendering Crossroads' status in a web page</a></dt> -<dt><a href="#l75">5.14: Crossroads and DNS caching</a></dt> +<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> </dl> -<dt><h3><a href="#l76">6: Benchmarking</a></h3></dt> +<dt><h3><a href="#l78">6: Benchmarking</a></h3></dt> <dl> -<dt><a href="#l77">6.1: Benchmark 1: Accessing a proxy via crossroads or directly</a></dt> +<dt><a href="#l79">6.1: Benchmark 1: Accessing a proxy via crossroads or directly</a></dt> <dl> -<dt><a href="#l78">6.1.1: Results</a></dt> -<dt><a href="#l79">6.1.2: Discussion</a></dt> +<dt><a href="#l80">6.1.1: Results</a></dt> +<dt><a href="#l81">6.1.2: Discussion</a></dt> </dl> -<dt><a href="#l80">6.2: Benchmark 2: Crossroads versus Linux Virtual Server (LVS)</a></dt> +<dt><a href="#l82">6.2: Benchmark 2: Crossroads versus Linux Virtual Server (LVS)</a></dt> <dl> -<dt><a href="#l81">6.2.1: Environment</a></dt> -<dt><a href="#l82">6.2.2: Tests and results</a></dt> +<dt><a href="#l83">6.2.1: Environment</a></dt> +<dt><a href="#l84">6.2.2: Tests and results</a></dt> </dl> </dl> -<dt><h3><a href="#l83">7: Compiling and Installing</a></h3></dt> +<dt><h3><a href="#l85">7: Compiling and Installing</a></h3></dt> <dl> -<dt><a href="#l84">7.1: Prerequisites</a></dt> -<dt><a href="#l85">7.2: Compiling and installing</a></dt> -<dt><a href="#l86">7.3: Configuring crossroads</a></dt> -<dt><a href="#l87">7.4: A boot script</a></dt> +<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> <dl> -<dt><a href="#l88">7.4.1: SysV Style Startup</a></dt> -<dt><a href="#l89">7.4.2: BSD Style Startup</a></dt> +<dt><a href="#l90">7.4.1: SysV Style Startup</a></dt> +<dt><a href="#l91">7.4.2: BSD Style Startup</a></dt> </dl> <p><hr><p> @@ -574,7 +576,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.13</a> for more information.) +web. (See section <a href="crossroads.html#xmlstatus">5.14</a> for more information.) <p> <a name="l15"></a> <h3>3.3: Logging-related options</h3> @@ -692,6 +694,28 @@ service web { <p> The <code>port</code> statement is then read as <code>port 80</code>. <p> +The statement <code>#define</code> can also be very nicely used when trying out +Crossroads configurations. Crossroads has a statement <code>verbosity</code> +<code>true</code> that causes debugging information to be logged. Once a +configuration has proven to work, you'll most likely want +<code>verbosity</code> <code>false</code> so that overhead due to logging is +avoided. This can be easily implemented using <code>#define</code>: +<p> +<pre> +/* Set DEBUG to true or false; + * true is for testing purposes, + * false is for production */ +#define DEBUG true + +service web { + verbosity DEBUG; + . + . /* More statements follow here */ + . +} +</pre> + +<p> <a name="l21"></a> <strong>4.1.3: Keywords, numbers, identifiers, generic strings</strong> <p> @@ -751,8 +775,18 @@ identifying names differ. The following list shows possible statements. Each statement must end with a semicolon, except for the <code>backend</code> statement, which has is own block (more on this later). <p> -<a name="conf/type"></a><a name="l23"></a> -<strong>4.2.1: type - Defining the service type</strong> <a name="conftype - Defining the service type"></a> +<a name="conf/port"></a><a name="l23"></a> +<strong>4.2.1: port - Specifying the listen port</strong> <a name="confport - Specifying the listen port"></a> + <dl> + <p><dt><strong>Description:</strong><dd> The <code>port</code> statement defines to which TCP port a service + 'listens'. E.g. <code>port 8000</code> says that this service will accept + connections on port 8000. + <p><dt><strong>Syntax:</strong><dd> <code>port</code> <em>number</em> + <p><dt><strong>Default:</strong><dd> There is no default. This is a required setting. + </dl> +<p> +<a name="conf/type"></a><a name="l24"></a> +<strong>4.2.2: type - Defining the service type</strong> <a name="conftype - Defining the service type"></a> <dl> <p><dt><strong>Description:</strong><dd> The <code>type</code> statement defines how crossroads handles the stated service. There are currently two types: <code>any</code> and @@ -771,18 +805,25 @@ Unless you really need such special features, use the type <code>any</code> (the <p><dt><strong>Default:</strong><dd> <code>any</code> </dl> <p> -<a name="conf/port"></a><a name="l24"></a> -<strong>4.2.2: port - Specifying the listen port</strong> <a name="confport - Specifying the listen port"></a> +<a name="conf/headerinspection"></a><a name="l25"></a> +<strong>4.2.3: headerinspection - are all HTTP headers inspected</strong> <a name="confheaderinspection - are all HTTP headers inspected"></a> <dl> - <p><dt><strong>Description:</strong><dd> The <code>port</code> statement defines to which TCP port a service - 'listens'. E.g. <code>port 8000</code> says that this service will accept - connections on port 8000. - <p><dt><strong>Syntax:</strong><dd> <code>port</code> <em>number</em> - <p><dt><strong>Default:</strong><dd> There is no default. This is a required setting. + <p><dt><strong>Description:</strong><dd> The <code>headerinspection</code> directive defines whether Crossroads +must inspect all HTTP headers that are seen on one TCP connection, or +only the first ones. There are two possible values for this directive: +<code>deep</code> and <code>shallow</code>. In <code>deep</code> mode, all information that is +seen on the TCP link is monitored +and parsed, and all HTTP header blocks are analyzed and subject to +directives such as <code>addclientheader</code>. In <code>shallow</code> mode, only the +first header block that the server sends, and the first header block +that forms the server's answer, are analyzed. + <p><dt><strong>Syntax:</strong><dd> <code>headerinspection</code> <em>specifier</em>, where <em>specifier</em> is +<code>deep</code> or <code>shallow</code> + <p><dt><strong>Default:</strong><dd> <code>deep</code> </dl> <p> -<a name="conf/bindto"></a><a name="l25"></a> -<strong>4.2.3: bindto - Binding to a specific IP address</strong> <a name="confbindto - Binding to a specific IP address"></a> +<a name="conf/bindto"></a><a name="l26"></a> +<strong>4.2.4: bindto - Binding to a specific IP address</strong> <a name="confbindto - Binding to a specific IP address"></a> <dl> <p><dt><strong>Description:</strong><dd> The <code>bindto</code> statement is used in situations where crossroads should only listen to the stated port at a given IP address. E.g., @@ -795,8 +836,8 @@ Unless you really need such special features, use the type <code>any</code> (the <p><dt><strong>Default:</strong><dd> <code>any</code> </dl> <p> -<a name="conf/verbose"></a><a name="l26"></a> -<strong>4.2.4: verbosity - Controlling debug output</strong> <a name="confverbosity - Controlling debug output"></a> +<a name="conf/verbose"></a><a name="l27"></a> +<strong>4.2.5: verbosity - Controlling debug output</strong> <a name="confverbosity - Controlling debug output"></a> <dl> <p><dt><strong>Description:</strong><dd> Verbosity statements come in two forms: <code>verbosity on</code> or <code>verbosity off</code>. When 'on', log messages to <code>/var/log/messages</code> @@ -812,12 +853,12 @@ Unless you really need such special features, use the type <code>any</code> (the <p><dt><strong>Default:</strong><dd> <code>off</code> </dl> <p> -<a name="conf/dispatchmode"></a><a name="l27"></a> -<strong>4.2.5: dispatchmode - How are back ends selected</strong> <a name="confdispatchmode - How are back ends selected"></a> +<a name="conf/dispatchmode"></a><a name="l28"></a> +<strong>4.2.6: dispatchmode - How are back ends selected</strong> <a name="confdispatchmode - How are back ends selected"></a> <dl> <p><dt><strong>Description:</strong><dd> 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 <a href="crossroads.html#howselected">5.1</a> for a textual explanation. + syntax. See section <a href="crossroads.html#howselected">5.2</a> for a textual explanation. <p> The settings can be: <p> @@ -875,7 +916,7 @@ The modifier <code>over</code> <em>connections</em> is optional. (The square custom-made dispatch modes are needed. <p> The dispatch mode that uses an <code>externalhandler</code> is - discussed separately in section <a href="crossroads.html#externalhandler">5.3</a>.</ul> + discussed separately in section <a href="crossroads.html#externalhandler">5.10</a>.</ul> <p> The selection algorithm is only used when clients are serviced that aren't part of a sticky HTTP session. This is the case during: @@ -899,8 +940,8 @@ Your 'right' dispatch mode will depend on the type of service. Given <p><dt><strong>Default:</strong><dd> <code>roundrobin</code> </dl> <p> -<a name="conf/revivinginterval"></a><a name="l28"></a> -<strong>4.2.6: revivinginterval - Back end wakeup calls</strong> <a name="confrevivinginterval - Back end wakeup calls"></a> +<a name="conf/revivinginterval"></a><a name="l29"></a> +<strong>4.2.7: revivinginterval - Back end wakeup calls</strong> <a name="confrevivinginterval - Back end wakeup calls"></a> <dl> <p><dt><strong>Description:</strong><dd> A reviving interval definition is needed when crossroads determines that a back end is temporarily unavailable. This will @@ -921,8 +962,8 @@ An example of the definition is <code>revivinginterval 10</code>. When this <p><dt><strong>Default:</strong><dd> 0 (no wakeup calls) </dl> <p> -<a name="conf/maxconnections"></a><a name="l29"></a> -<strong>4.2.7: maxconnections - Limiting concurrent clients at service level</strong> <a name="confmaxconnections - Limiting concurrent clients at service level"></a> +<a name="conf/maxconnections"></a><a name="l30"></a> +<strong>4.2.8: maxconnections - Limiting concurrent clients at service level</strong> <a name="confmaxconnections - Limiting concurrent clients at service level"></a> <dl> <p><dt><strong>Description:</strong><dd> The maximum number of connections is specified using <code>maxconnections</code>. There is one argument; the number of concurrent @@ -937,8 +978,8 @@ An example of the definition is <code>revivinginterval 10</code>. When this <p><dt><strong>Default:</strong><dd> 0, meaning that all connections will be accepted. </dl> <p> -<a name="conf/backlog"></a><a name="l30"></a> -<strong>4.2.8: backlog - The TCP Back Log size</strong> <a name="confbacklog - The TCP Back Log size"></a> +<a name="conf/backlog"></a><a name="l31"></a> +<strong>4.2.9: backlog - The TCP Back Log size</strong> <a name="confbacklog - The TCP Back Log size"></a> <dl> <p><dt><strong>Description:</strong><dd> The TCP back log size is a number that controls how many 'waiting' network connections may be queued, before a client simply @@ -953,8 +994,8 @@ An example of the definition is <code>revivinginterval 10</code>. When this value for socket back log size. </dl> <p> -<a name="conf/shmkey"></a><a name="l31"></a> -<strong>4.2.9: shmkey - Shared Memory Access</strong> <a name="confshmkey - Shared Memory Access"></a> +<a name="conf/shmkey"></a><a name="l32"></a> +<strong>4.2.10: shmkey - Shared Memory Access</strong> <a name="confshmkey - Shared Memory Access"></a> <dl> <p><dt><strong>Description:</strong><dd> Different Crossroads invocations must 'know' of each others activity. E.g, <code>crossroad @@ -973,8 +1014,9 @@ The actual key value doesn't matter much, as long as it's unique <p><dt><strong>Default:</strong><dd> 0, which means that crossroads will 'guess' its own key, based on the service name. </dl> -<a name="conf/allow"></a><a name="l32"></a> -<strong>4.2.10: allow* and deny* - Allowing or denying connections</strong> <a name="confallow* and deny* - Allowing or denying connections"></a> +<p> +<a name="conf/allow"></a><a name="l33"></a> +<strong>4.2.11: allow* and deny* - Allowing or denying connections</strong> <a name="confallow* and deny* - Allowing or denying connections"></a> <dl> <p><dt><strong>Description:</strong><dd> Crossroads can allow or deny connections based on the IP address of a client. There are four @@ -1042,8 +1084,8 @@ This is probably best explained by a few examples: <p><dt><strong>Default:</strong><dd> In absence of these statements, all client IP's are accepted. </dl> <p> -<a name="conf/useraccount"></a><a name="l33"></a> -<strong>4.2.11: useraccount - Limiting the effective ID of external processes</strong> <a name="confuseraccount - Limiting the effective ID of external processes"></a> +<a name="conf/useraccount"></a><a name="l34"></a> +<strong>4.2.12: useraccount - Limiting the effective ID of external processes</strong> <a name="confuseraccount - Limiting the effective ID of external processes"></a> <dl> <p><dt><strong>Description:</strong><dd> Using the directive <code>useraccount</code>, the effective user and group ID can be restricted. This comes into effect when Crossroads runs @@ -1060,7 +1102,7 @@ This is probably best explained by a few examples: ID that was in effect when Crossroads was started. </dl> <p> -<a name="l34"></a> +<a name="l35"></a> <h3>4.3: Backend definitions</h3> <p> Inside the service definitions as are described in the previous @@ -1096,7 +1138,7 @@ Crossroads treats the network traffic as a stream of HTTP messages; i.e., when the service is declared with <code>type http</code>. Incase of <code>type any</code>, the HTTP-specific directives have no effect. <p> -<a name="conf/server.yo"></a><a name="l35"></a> +<a name="conf/server.yo"></a><a name="l36"></a> <strong>4.3.1: server - Specifying the back end address</strong> <a name="confserver - Specifying the back end address"></a> <dl> <p><dt><strong>Description:</strong><dd> Each back end must be identified by the network name @@ -1115,7 +1157,7 @@ i.e., when the service is declared with <code>type http</code>. Incase of <p><dt><strong>Default:</strong><dd> There is no default. This is a required setting. </dl> <p> -<a name="conf/verbose-backend.yo"></a><a name="l36"></a> +<a name="conf/verbose-backend.yo"></a><a name="l37"></a> <strong>4.3.2: verbosity - Controlling verbosity at the back end level</strong> <a name="confverbosity - Controlling verbosity at the back end level"></a> <dl> <p><dt><strong>Description:</strong><dd> Similar to <code>service</code> specifications, a @@ -1129,7 +1171,7 @@ i.e., when the service is declared with <code>type http</code>. Incase of <p><dt><strong>Default:</strong><dd> <code>off</code> </dl> <p> -<a name="conf/retries.yo"></a><a name="l37"></a> +<a name="conf/retries.yo"></a><a name="l38"></a> <strong>4.3.3: retries - Specifying allowed failures</strong> <a name="confretries - Specifying allowed failures"></a> <dl> <p><dt><strong>Description:</strong><dd> Back ends that are 'flaky' or on a less reliable network can be @@ -1144,7 +1186,7 @@ i.e., when the service is declared with <code>type http</code>. Incase of connection. </dl> <p> -<a name="conf/weight"></a><a name="l38"></a> +<a name="conf/weight"></a><a name="l39"></a> <strong>4.3.4: weight - When a back end is more equal than others</strong> <a name="confweight - When a back end is more equal than others"></a> <dl> <p><dt><strong>Description:</strong><dd> To influence how backends are selected, a backend can specify its @@ -1163,7 +1205,7 @@ The weighing mechanism only applies to the dispatch modes <p><dt><strong>Default:</strong><dd> 1; all back ends have equal weight. </dl> <p> -<a name="conf/decay"></a><a name="l39"></a> +<a name="conf/decay"></a><a name="l40"></a> <strong>4.3.5: decay - Levelling out activity of a back end</strong> <a name="confdecay - Levelling out activity of a back end"></a> <dl> <p><dt><strong>Description:</strong><dd> To make sure that a 'spike' of activity doesn't @@ -1185,7 +1227,7 @@ This means that when a given back end is hit, then its usage data <p><dt><strong>Default:</strong><dd> 0, meaning that no decay is applied to usage statistics. </dl> <p> -<a name="conf/onhooks"></a><a name="l40"></a> +<a name="conf/onhooks"></a><a name="l41"></a> <strong>4.3.6: onstart, onend, onfail - Action Hooks</strong> <a name="confonstart, onend, onfail - Action Hooks"></a> <dl> <p><dt><strong>Description:</strong><dd> The three directives <code>onstart</code>, <code>onend</code> and <code>onfail</code> can be @@ -1237,7 +1279,7 @@ The format is always <code>on</code><em>type</em> <em>command</em>. The <em>comm connection, success or failure of a back end. </dl> <p> -<a name="conf/trafficlog"></a><a name="l41"></a> +<a name="conf/trafficlog"></a><a name="l42"></a> <strong>4.3.7: trafficlog and throughputlog - Debugging and Performance Aids</strong> <a name="conftrafficlog and throughputlog - Debugging and Performance Aids"></a> <dl> <p><dt><strong>Description:</strong><dd> Two directives are available @@ -1257,7 +1299,7 @@ The <code>throughputlog</code> statement writes shorthand transmissions to <p><dt><strong>Default:</strong><dd> none </dl> <p> -<a name="conf/stickycookie"></a><a name="l42"></a> +<a name="conf/stickycookie"></a><a name="l43"></a> <strong>4.3.8: stickycookie - Back end selection with an HTTP cookie</strong> <a name="confstickycookie - Back end selection with an HTTP cookie"></a> <dl> <p><dt><strong>Description:</strong><dd> The directive <code>stickycookie</code> <em>value</em> @@ -1297,7 +1339,7 @@ There are basically to provide such cookies to a browser. First, a <p><dt><strong>Default:</strong><dd> There is no default. </dl> <p> -<a name="conf/addclientheader"></a><a name="l43"></a> +<a name="conf/addclientheader"></a><a name="l44"></a> <strong>4.3.9: HTTP Header Modification Directives</strong> <a name="confHTTP Header Modification Directives"></a> <dl> <p><dt><strong>Description:</strong><dd> Crossroads understands the following @@ -1473,155 +1515,402 @@ service ... { <p><dt><strong>Default:</strong><dd> There is no default. </dl> <p> -<a name="l44"></a> +<a name="l45"></a> <h2>5: Tips, Tricks and Random Remarks</h2> <a name="tips"></a>The following sections elaborate on the directives as described in section <a href="crossroads.html#config">4</a> to illustrate how crossroads works and to help you achieve the "optimal" balancing configuration. <p> -<a name="l45"></a> -<h3>5.1: How back ends are selected in load balancing</h3> <a name="howselected"></a> -<a name="tips/howselected"></a>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 <code>bysize</code>, <code>byduration</code> -and <code>byconnections</code> only. The other dispatching types are -self-explanatory. -<p> <a name="l46"></a> -<strong>5.1.1: Bysize, byduration or byconnections?</strong> -<p> -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: -<p> -<ul> - <li> In general, a service which is CPU bound, will be more - busy when it takes longer to process a request. The dispatch - mode <code>byduration</code> is appropriate here. -<p> -<li> In contrast, a service which is filesystem bound, will be - more busy when more data are transferred. The dispatch mode - <code>bysize</code> is apppropriate. -<p> -<li> The dispatch mode <code>byduration</code> can also be used when - network latency is an issue. E.g., if your balancer has back - ends that are geograpically distributed, then <code>byduration</code> - would be a good way to select best available back ends. -<p> -<li> Furthermore it is noteworthy that <code>dispatchmode - byduration</code> 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 <code>byduration</code> should only be used for automated - processes that don't wait for user interaction (e.g., SOAP - calls and other HTTP requests). -<p> -<li> As a last remark, the dispatching mode <code>byconnections</code> can - be used if you don't have other clues for load - estimations. -<p> -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 <code>select</code> 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, <code>byduration</code> - 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 <code>byconnections</code> may be - your best bet. -<p> -</ul> -<p> +<h3>5.1: Configuration examples</h3> +<a name="tips/examples"></a> <a name="l47"></a> -<strong>5.1.2: Averaging size and duration</strong> -<p> -The configuration statement <code>dispatchmode bysize</code> or <code>byduration</code> -allows an optional modifier <code>over</code> <em>number</em>, where the stated -number represents a connection count. When this modifier is present, then -crossroads will use a moving average over the last <em>n</em> connections to -compute duration and size figures. -<p> -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 <code>over</code> 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. +<strong>5.1.1: A load balancer for three webserver back ends</strong> <p> -In contrast, when e.g. <code>over 3</code> is in effect, then a sudden load -does show up -- because it highly contributes to the average of three -connections. -<p> -<a name="l48"></a> -<strong>5.1.3: Specifying decays</strong> -<p> -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. -<p> -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. -<p> -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 <strong>other</strong> back ends are hit. The decay parameter -is like specifying how fast your body regenerates when someone else -does the work. -<p> -The below configuration illustrates this: +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. <p> <pre> -/* Definition of the service */ -service soap { - /* Local TCP port */ - port 8080; +service www { + /* We don't need session stickyness. */ + type any; + + /* Port on which we'll listen in this service: required. */ + port 8000; - /* We'll select back ends by the processing - * duration + /* 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 3; + dispatchmode byduration over 5; - /* First back end: */ - backend A { - /* Back end IP address and port */ - server 10.1.1.1:8080; + /* 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; - /* When this back end is NOT hit because - * the other one was less busy, then the - * usage parameters decay 10% per connection + /* 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; } - /* Second back end: */ - backend B { - server 10.1.1.2:8080; + /* 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; } } </pre> <p> -<a name="l49"></a> -<strong>5.1.4: Adjusting the weights</strong> -<p> -The back end modifier <code>weight</code> 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. +<a name="l48"></a> +<strong>5.1.2: An HTTP forwarder when travelling</strong> <p> -Or you may have -one primary back end, a system with a fast CPU and enough memory, and a +As another example, here's my /etc/crossroads.conf 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. +<p> +Here's how it used to be before crossroads: +<p> +<ul> + <li> At home, I would surf through a squid proxy on my local + machine. The browser proxy setting is then + <code>http://localhost:3128</code>. +<p> +<li> 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 + <code>http://localhost:3129</code>. +<p> +<li> At a customer's location I need the proxy + <code>http://10.120.34.113:8080</code>, because they have configured it + so. +<p> +<li> And in yet other instances, I use a HTTP diagnostic tool + <a href="http://www.xk72.com/charles">Charles</a> + 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 + <code>http://localhost:8888</code>.</ul> +<p> +Here's how it works with a crossroads configuration: +<p> +<ul> + <li> I have configured my browsers to use + <code>http://localhost:8080</code> as the proxy. For all situations. +<p> +<li> I use the following crossroads configuration, and let + crossroads figure out which proxy backend works, and which + doesn't. Note two particularities: +<p> +<ul> + <li> The statement <code>dispatchmode byorder</code>. 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. +<p> +<li> The statement <code>bindto 127.0.0.1</code> makes sure + that requests from other interfaces than loopback + won't get serviced.</ul> +<p> +<pre> +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; + } +} +</pre> +</ul> +<p> +As a final note, the commandline argument <code>tell</code> 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 <code>SshTunnel</code> +and <code>LocalSquid</code> are both active, then <code>crossroads tell httpproxy +sshtunnel down</code> will 'take down' the back end <code>SshTunnel</code> -- and +will automatically cause crossroads to switch to <code>LocalSquid</code>. +<p> +<a name="l49"></a> +<strong>5.1.3: SSH login with enforced idle logout</strong> +<p> +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. +<p> +Note the usage of the +<code>connectiontimeout</code> directive. This makes sure that users are logged +out after 10 minutes of inactivity. Note also the <code>maxconnections</code> +setting, this makes sure that no more than 10 concurrent logins occur. +<p> +<pre> +service Ssh { + port 22; + backlog 5; + maxconnections 10; + connectiontimeout 600; + backend TrueSshDaemon { + server localhost:2222; + } +} +</pre> + +<p> +<a name="l50"></a> +<h3>5.2: How back ends are selected in load balancing</h3> <a name="howselected"></a> +<a name="tips/howselected"></a>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 <code>bysize</code>, <code>byduration</code> +and <code>byconnections</code> only. The other dispatching types are +self-explanatory. +<p> +<a name="l51"></a> +<strong>5.2.1: Bysize, byduration or byconnections?</strong> +<p> +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: +<p> +<ul> + <li> In general, a service which is CPU bound, will be more + busy when it takes longer to process a request. The dispatch + mode <code>byduration</code> is appropriate here. +<p> +<li> In contrast, a service which is filesystem bound, will be + more busy when more data are transferred. The dispatch mode + <code>bysize</code> is apppropriate. +<p> +<li> The dispatch mode <code>byduration</code> can also be used when + network latency is an issue. E.g., if your balancer has back + ends that are geograpically distributed, then <code>byduration</code> + would be a good way to select best available back ends. +<p> +<li> Furthermore it is noteworthy that <code>dispatchmode + byduration</code> 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 <code>byduration</code> should only be used for automated + processes that don't wait for user interaction (e.g., SOAP + calls and other HTTP requests). +<p> +<li> As a last remark, the dispatching mode <code>byconnections</code> can + be used if you don't have other clues for load + estimations. +<p> +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 <code>select</code> 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, <code>byduration</code> + 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 <code>byconnections</code> may be + your best bet. +<p> +</ul> +<p> +<a name="l52"></a> +<strong>5.2.2: Averaging size and duration</strong> +<p> +The configuration statement <code>dispatchmode bysize</code> or <code>byduration</code> +allows an optional modifier <code>over</code> <em>number</em>, where the stated +number represents a connection count. When this modifier is present, then +crossroads will use a moving average over the last <em>n</em> connections to +compute duration and size figures. +<p> +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 <code>over</code> 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. +<p> +In contrast, when e.g. <code>over 3</code> is in effect, then a sudden load +does show up -- because it highly contributes to the average of three +connections. +<p> +<a name="l53"></a> +<strong>5.2.3: Specifying decays</strong> +<p> +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. +<p> +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. +<p> +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 <strong>other</strong> back ends are hit. The decay parameter +is like specifying how fast your body regenerates when someone else +does the work. +<p> +The below configuration illustrates this: +<p> +<pre> +/* 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; + } +} +</pre> + +<p> +<a name="l54"></a> +<strong>5.2.4: Adjusting the weights</strong> +<p> +The back end modifier <code>weight</code> 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. +<p> +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. @@ -1666,8 +1955,8 @@ 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. <p> -<a name="l50"></a> -<h3>5.2: Throttling the number of concurrent connections</h3> +<a name="l55"></a> +<h3>5.3: Throttling the number of concurrent connections</h3> <a name="tips/throttling"></a>If you suspect that your service may occasionally receive 'spikes' of activity&nbsp;(which you should always assume), then it might be a good idea to protect your service by specifying a maximum number of @@ -1695,721 +1984,356 @@ too much, a situation may occur where that back end is about to be hit. A <code>maxconnections</code> statement on the level of that back may then protect it. <p> -<a name="l51"></a> -<h3>5.3: Using an external program to dispatch</h3> <a name="externalhandler"></a> -<a name="tips/externalhandler"></a>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. -<p> -<a name="l52"></a> -<strong>5.3.1: Configuring the external handler</strong> +<a name="l56"></a> +<h3>5.4: TCP Session Stickiness</h3> +<a name="tips/tcpstickiness"></a>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 <code>byclientip</code>. 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). <p> -First, the <code>dispatchmode</code> statement needs to inform Crossroads that -an external program will do the job. The syntax is: <code>dispatchmode -externalhandler</code> <em>program arguments</em>. The <em>program</em> must point to -an executable program that will be started by Crossroads. The -specifier <em>arguments</em> can be anything you want; those will be the -arguments to Crossroads. You can however use the following special -format specifiers: +The <code>dispatchmode byclientip</code> works as follows: <p> <ul> - <li> <code>%a</code> is the availability of the current back end, when - a current back end is established; - <li> <code>%1a</code> is the availability of the first back end (0 when - unavailable, 1 if available); <code>%2a</code> is the availability of - the second back end, and so on; - <li> <code>%b</code> is the name of the current back end, when one is - established; - <li> <code>%1b</code> is the name of the first back end, <code>%2b</code> of the - second back end, and so on; - <li> <code>%e</code> is the count of seconds since start of epoch - (January 1st 1970 GMT); - <li> <code>%r</code> is the IP address of the client that requests a - connection and for whom the external dispatcher should compute - a back end; - <li> <code>%s</code> is the name of the current service that the client - connected to; - <li> <code>%t</code> is the current local time in ASCII format, in - <em>YYYY-MM-DD/hhh:mm:ss</em>; - <li> <code>%T</code> is the current GMT time in ASCIII format; - <li> <code>%v</code> is the Crossroads version; - <li> Any other chararacter following a <code>%</code> sign is taken - literally; e.g. <code>%z</code> is just a z.</ul> + <li> The client's IP address is taken in its string + representation and 'hashed' into a number. <p> -Note that the format specifiers such as <code>%b</code> 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). +<li> The number is brought back to the number of available + back ends (using a modulo-operation). <p> -<a name="l53"></a> -<strong>5.3.2: Writing the external handler</strong> +<li> The result defines the back end of choice.</ul> <p> -The external handler is activated using the arguments that are -specified in /etc/crossroads.conf. The external handler can do -whatever it wants, but ultimately, it must write a back end name on -its <em>stdout</em>. Crossroads reads this, and if the back end is -available, uses that back end for the connection. +If the preferred back end is unavailable, then the action that +Crossroads takes is to dispatch as if <code>byconnections</code>: of the +available back ends, the one with the least connections is taken. <p> -<a name="l54"></a> -<strong>5.3.3: Examples of external handlers</strong> +<a name="l57"></a> +<h3>5.5: HTTP Session Stickiness</h3> +<a name="tips/httpstickiness"></a>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. <p> -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 -<code>etc/</code>. 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. +<a name="l58"></a> +<strong>5.5.1: Don't use stickiness!</strong> <p> -<p><strong>Round-robin dispatching</strong><br> +The rule of thumb as far as the balancer is concerned, is: <strong>Do not +use HTTP session stickiness unless you really have to.</strong> Enabling +session stickiness hampers failover, balancing and performance: <p> -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. +<ul> + <li> 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.) + <li> 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. + <li> 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.</ul> <p> -The Crossroads configuration is shown below: +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. +<p> +<a name="l59"></a> +<strong>5.5.2: But if you must..</strong> +<p> +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: <p> <pre> -service test { - port 8001; - verbosity on; - revivinginterval 5; - - dispatchmode externalhandler - /usr/local/src/crossroads/etc/dispatcher-roundrobin - %1b %1a %2b %2a; +service www { + port 80; + type any; + revivinginterval 15; + dispatchmode byclientip; - backend testone { - server localhost:3128; - verbosity on; + backend one { + server 10.1.1.100:80; } - backend testtwo { - server locallhost:3128; - verbosity on; + + backend two { + server 10.1.1.101:80; } } </pre> <p> -The relevant <code>dispatchmode</code> statement invokes the external program -<code>dispatcher-roundrobin</code> with four arguments: the name of the first -back end (<code>testone</code>), its availability (0 or 1), the name of the -second back end (<code>testtwo</code>) and its availability (0 or 1). +However, if you <strong>must</strong> use HTTP-base session stickiness, then +proceed as follows: <p> -The external handler, which is also included in the Crossroads -distribution, is shown below. It is a Perl script. +<ul> + <li> At the level of a <code>service</code> description, set the type to + <code>http</code>. + <li> Furthermore, set the <code>headerinspection</code> to <code>shallow</code> + (unless of course you also want to modify other HTTP headers, + see section <a href="crossroads.html#tips/deeporshallow">5.7</a>). + <li> At the level of each back end description, configure the + <code>stickycookie</code> and a <code>addclientheader</code> directives.</ul> +<p> +Once crossroads sees that, it will examine each HTTP message that it +shuttles between client and back end: +<p> +<ul> + <li> 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 <code>Set-Cookie</code> directive. + <li> 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.</ul> +<p> +Below is a short example of a configuration. <p> <pre> -#!/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, "&gt;&gt;$log") or return; - print $of (scalar(localtime()), ' ', @_); -} - -# Read the last used back end -# --------------------------- -sub readlast() { - my $ret; - - if (open (my $if, $statefile)) { - $ret = &lt;$if&gt;; - chomp ($ret); - close ($if); - msg ("Last used back end: $ret\n"); - return ($ret); - } - msg ("No last-used back end (yet)\n"); - return (undef); -} - -# Write back the last used back end, reply to Crossroads and stop -# --------------------------------------------------------------- -sub reply ($) { - my $last = shift; +service www { + port 80; + type http; + headerinspection shallow; + revivinginterval 15; + dispatchmode byconnections; - if (open (my $of, "&gt;$statefile")) { - print $of ("$last\n"); + backend one { + server 10.1.1.100:80; + stickycookie XRID=100; + addclientheader "Set-Cookie: XRID=100; Path=/"; } - print ("$last\n"); - 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\n"); -my @backend; -for (my $i = 0; $i &lt;= $#ARGV; $i += 2) { - push (@backend, $ARGV[$i]) if ($ARGV[$i + 1]); -} -msg ("Available back ends: @backend\n"); - -# 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]\n"); - 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 &lt; $#backend; $i++) { - if ($last eq $backend[$i]) { - msg ("Returning next back end ", $backend[$i + 1], "\n"); - reply ($backend[$i + 1]); + backend two { + server 10.1.1.101:80; + stickycookie XRID=101; + addclientheader "Set-Cookie: XRID=101; Path=/"; } } - -# No luck.. run back to the first one. -msg ("Returning first back end $backend[0]\n"); -reply ($backend[0]); </pre> <p> -The working of the script is basically as follows: +Note how the cookie names and values in the directives +<code>stickycookie</code> and <code>addclientheader</code> match. That is obviously a +prerequisite for stickiness. +<p> +<a name="l60"></a> +<h3>5.6: Passing the client's IP address</h3> +<a name="tips/clientip"></a>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. +<p> +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: <p> <ul> - <li> The argument list is scanned. Back ends that are - available are collected in an array <code>@backend</code>. + <li> The service type must be <code>http</code>, and not <code>any</code>; + <li> Make sure that the <code>headerinspection</code> is <code>deep</code> (or that + there is no <code>headerinspection</code> statement, since <code>deep</code> is + the default, see section <a href="crossroads.html#tips/deeporshallow">5.7</a>); + <li> In the back end definition, the following statement must + occur: <br> + <code>addserverheader "X-Real-IP: %r";</code> <br> + You are of course free to choose the header name; the here + used <code>X-Real-IP</code> is a common name for this purpose.</ul> <p> -<li> The script queries a state file <code>/tmp/rr.last</code>. If a - back end name occurs there, then the next back end is looked - up in <code>@backend</code> and returned to Crossroads. If no last back - is unknown or can't be matched, then the first available back - end (first element of <code>@backend</code>) is returned to Crossroads. +After this, HTTP traffic that arrives at the back ends has a new +header: <code>X-Real-IP</code>, holding the client's IP address. +<strong>Note that</strong> once the type is set to <code>http</code>, Crossroads' +performance will be hampered -- all passing messages will have to be +unpacked and analyzed. <p> -<li> Informing Crossroads is done via the subroutine - <code>reply()</code>. This code writes the selected back end to file - <code>/tmp/rr.last</code> (for future usage) and prints the back end - name to <em>stdout</em>. +<a name="l61"></a> +<strong>5.6.1: Sample Crossroads configuration</strong> <p> -<li> The script logs its actions to a file - <code>/tmp/exthandler.log</code>. This log file can be inspected for - the script's actions.</ul> +The below sample configuration shows two HTTP back ends that receive +the client's IP address: <p> -<p><strong>Dispatching by the client IP address</strong><br> +<pre> + +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"; + } +} +</pre> + <p> -The following example shows a useful real-life situation that -illustrates how dispatching by client IP address works. <strong>Note that</strong> -as of Crossroads 1.31, <code>dispatchmode byclientip</code> 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. +<a name="l62"></a> +<strong>5.6.2: Sample Apache configuration</strong> <p> -The situation is as follows: +The method by which each back end analyzes the header <code>X-Real-IP</code> +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. <p> -<ul> - <li> 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; +Often this is accomplished using the log format <code>custom</code>, defined as +follows: <p> -<li> 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; +<pre> +LogFormat "%h %l %u %t %D \"%r\" %&gt;s %b" common +CustomLog logs/access_log common +</pre> + <p> -<li> Client PC's have their distinct IP addresses, which - distinguishes them. +The first line defines the format <code>common</code>, with the remote host +specified by <code>%h</code>. The second line sends access information to a log +file <code>logs/access_log</code>, using the previously defined format +<code>common</code>. <p> -<li> 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.</ul> +Furtunately, Apache's <code>LogFormat</code> allows one to log contents of +headers. By replacing the <code>%h</code> with <code>%{X-Real-IP}i</code>, the desired +information is sent to the log. Therefore, normally you can simply +redefine the <code>common</code> format to <p> -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: +<pre> +LogFormat "%{X-Real-IP}i %l %u %t %D \"%r\" %&gt;s %b" common +</pre> + <p> -<ul> - <li> A suitable dispatch mode isn't yet available in - Crossroads, but can be easily coded in an external handler; +<a name="l63"></a> +<h3>5.7: Deep or shallow HTTP header inspection</h3> +<a name="tips/deeporshallow"></a>The service-level directive <code>headerinspection</code> defines which HTTP +headers Crossroads will analyze. Often, several HTTP requests and +responses will be served over one network +link. Browsers and servers will try to keep a TCP link open so that it +may be re-used; this is a measure to increase efficiency and to shorten load +times of pages. E.g., a typical HTML page +will require a style sheet and a few images - and these can be +retrieved over the same link that originally served the HTML page. +<p> +Re-using the TCP link occurs more often than not. It is the default in +HTTP/1.1 (unless <code>Connection: close</code> is specified as one of the HTTP +headers). The older HTTP protocol, HTTP/1.0, by default passes just +one request and response over a TCP link, after which the link is +closed (unless <code>Connection: keep-alive</code> is specified as one of the +HTTP headers). +<p> +If you define your service as <code>type http</code>, then by default +Crossroads will inspect all HTTP headers that it sees: not only the +first browser request and server answer, but also subsequent requests +and answers that travel over the same link. This is called 'deep +inspection mode', in which Crossroads applies +directives such as <code>addclientheader</code> to all header +blocks. Inspecting the full TCP stream to catch header blocks can be +resource consuming. You can optionally make Crossroads's resource +consumption 'lighter' by instructing it to inspect only the first +HTTP header block, and to simply pass-through over all subsequent information +(which might well include next header blocks of a re-used TCP +connection) This is done using the directive <code>headerinspection</code>: <p> -<li> 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.</ul> +<pre> +service web { + type http; + headerinspection shallow; + backend a { .... } + backend b { .... } +} +</pre> + <p> -The approach to the solution of this problem uses several external -program hooks: +The situations where <code>shallow</code> mode can be used, depends on what you +need to do: <p> <ul> - <li> 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. - <li> An external hook <code>onstart</code> will be responsible for - updating the internal administration; i.e., to flag a back end - as 'occupied'. - <li> The external hooks <code>onfailure</code> and <code>onend</code> 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.</ul> -<p> -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). + <li> <code>shallow</code> mode can be used when the inspection and + modification of the first HTTP header block suffices. For example, + HTTP session stickiness is a good example: <p> <pre> -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; +service web { + type http; + headerinspection shallow; + backend a { + server 10.1.1.1:80; + stickycookie "BalancerID=1"; + addclientheader "Set-Cookie: BalancerID=1"; } + . + . other back ends are defined here + . } </pre> <p> -Depending on the dispatcher stage, the exernal handler <code>rdp-helper</code> -is invoked in different ways: -<p> -<dl> - <p><dt><strong>During dispatching</strong><dd> the helper is called to suggest a back - end. The arguments are an action indicator <code>dispatch</code>, 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. -<p> -<p><dt><strong>During connection start</strong><dd> the helper will be invoked to - inform it of the start of a connection, given a client IP - address. +In this case, Crossroads will inspect only the first header block that + the client sends for the presence of a cookie <code>BalancerID</code>. If the + cookie has value 1, then the request will be routed to back end + <code>a</code>. Similarly, Crossroads will inspect only the first header block + that the server sends, and will inject a <code>Set-Cookie</code> + instruction. <p> -<p><dt><strong>When a connection terminates</strong><dd> the helper will be invoked - to inform it that the connection has ended.</dl> +In this example, deep mode is not necessary because Crossroads + will use the first header that the client sends to route the + information to a given back end. + If more than one HTTP transactions follow over + the same TCP link, then by definition the link will go to the + same back end - even without inspecting all HTTP headers that + follow the first ones. <p> -Here's the external handler as Perl script. It uses the module -<code>GDBM_File</code> 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.) +<li> <code>deep</code> mode is necessary in situations where all header + blocks must be inspected and modified. E.g., if you want to hide your + HTTP server identification, you might use: <p> <pre> -#!/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, "&gt;&gt;$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.\n"); - print ("$b\n"); - exit (0); -} - -# Is a value in an array -# ---------------------- -sub inarray { - my $val = shift; - for my $other (@_) { - return (1) if ($other eq $val); +service web { + type http; + headerinspection deep; + backend a { + server 10.1.1.1:80; + setclientheader "Server: MyWebServer"; } - return (0); + . + . other back ends are defined here + . } - -# A connection is starting -# ------------------------ -sub start { - my ($ip, $stamp, $backend) = @_; - msg ("Logging START of connection for IP $ip on stamp $stamp, ", - "back end $backend\n"); - $db{$ip} = "$backend:$stamp"; -} - -# A connection has ended -# ---------------------- -sub end { - my $ip = shift; - msg ("Logging END of connection for IP $ip\n"); - $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\n"); - - # 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 &lt; $#_; $i += 3) { - if ($_[$i + 1] != 0) { - push (@backends, $_[$i]); - push (@weights, $_[$i + 2]); - msg ("Candidate back end: $_[$i] with weight ", $_[$i + 2], "\n"); - } - } - - # 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\n"); - if ($stamp &lt; $last_stamp + $timeout) { - msg ("Timeout not yet exceeded, this may be a reconnect\n"); - # 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\n"); - reply ($last_backend); - } else { - msg ("Last used back end isn't free, suggesting a new one\n"); - } - } else { - msg ("Timeout exceeded, suggesting a new back end\n"); - } - } else { - msg ("Np preveious connection data, suggesting a new back end\n"); - } - - my $bestweight = -1; - my $bestbackend; - for (my $i = 0; $i &lt;= $#weights; $i++) { - if ($bestweight == -1 or $bestweight &gt; $weights[$i]) { - $bestweight = $weights[$i]; - $bestbackend = $backends[$i]; - } - } - - msg ("Best back end: $bestbackend (given weight $bestweight)\n"); - reply ($bestbackend); -} - -# Main starts here -# ---------------- -msg ("Start of run, attaching GDBM database '$cdb'\n"); -tie (%db, 'GDBM_File', $cdb, &amp;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\n"); - exit (1); -} -</pre> - -<p> -<a name="l55"></a> -<h3>5.4: TCP Session Stickiness</h3> -<a name="tips/tcpstickiness"></a>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 <code>byclientip</code>. 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). -<p> -The <code>dispatchmode byclientip</code> works as follows: -<p> -<ul> - <li> The client's IP address is taken in its string - representation and 'hashed' into a number. -<p> -<li> The number is brought back to the number of available - back ends (using a modulo-operation). -<p> -<li> The result defines the back end of choice.</ul> -<p> -If the preferred back end is unavailable, then the action that -Crossroads takes is to dispatch as if <code>byconnections</code>: of the -available back ends, the one with the least connections is taken. -<p> -<a name="l56"></a> -<h3>5.5: HTTP Session Stickiness</h3> -<a name="tips/httpstickiness"></a>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. -<p> -<a name="l57"></a> -<strong>5.5.1: Don't use stickiness!</strong> -<p> -The rule of thumb as far as the balancer is concerned, is: <strong>Do not -use HTTP session stickiness unless you really have to.</strong> Enabling -session stickiness hampers failover, balancing and performance: -<p> -<ul> - <li> 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.) - <li> 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. - <li> 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.</ul> -<p> -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. -<p> -<a name="l58"></a> -<strong>5.5.2: But if you must..</strong> -<p> -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: -<p> -<pre> -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; - } -} -</pre> - -<p> -However, if you <strong>must</strong> use HTTP-base session stickiness, then -proceed as follows: -<p> -<ul> - <li> At the level of a <code>service</code> description, set the type to - <code>http</code>. - <li> At the level of each back end description, configure the - <code>stickycookie</code> and a <code>addclientheader</code> directives.</ul> -<p> -Once crossroads sees that, it will examine each HTTP message that it -shuttles between client and back end: -<p> -<ul> - <li> 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 <code>Set-Cookie</code> directive. - <li> 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.</ul> -<p> -Below is a short example of a configuration. -<p> -<pre> -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=/"; - } -} -</pre> +</pre> <p> -Note how the cookie names and values in the directives -<code>stickycookie</code> and <code>addclientheader</code> match. That is obviously a -prerequisite for stickiness. +Here, all HTTP header blocks that come from the server will be parsed, + and <code>Server</code> headers will be overwritten. + In a similar vein, if you want to pass the client's IP address, you + will also need deep mode. <p> -<a name="l59"></a> -<h3>5.6: Passing the client's IP address</h3> -<a name="tips/clientip"></a>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. -<p> -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: -<p> -<ul> - <li> The service type must be <code>http</code>, and not <code>any</code>; - <li> In the back end definition, the following statement must - occur: <br> - <code>addserverheader "X-Real-IP: %r";</code> <br> - You are of course free to choose the header name; the here - used <code>X-Real-IP</code> is a common name for this purpose.</ul> -<p> -After this, HTTP traffic that arrives at the back ends has a new -header: <code>X-Real-IP</code>, holding the client's IP address. -<strong>Note that</strong> once the type is set to <code>http</code>, Crossroads' -performance will be hampered -- all passing messages will have to be -unpacked and analyzed. +In these examples, <code>shallow</code> mode is not usable, because the + outbound header modifications should apply to all headers of a + given series. Imagine that one would use <code>shallow</code> mode + here: then, in a series of 5 HTTP transactions that pass over + the same TCP link, only the first transaction would hide the + HTTP server signature. All subsequent transactions would still + show the HTTP server signature to the world.</ul> <p> -<a name="l60"></a> -<strong>5.6.1: Sample Crossroads configuration</strong> -<p> -The below sample configuration shows two HTTP back ends that receive -the client's IP address: -<p> -<pre> - -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"; - } -} -</pre> - -<p> -<a name="l61"></a> -<strong>5.6.2: Sample Apache configuration</strong> -<p> -The method by which each back end analyzes the header <code>X-Real-IP</code> -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. -<p> -Often this is accomplished using the log format <code>custom</code>, defined as -follows: -<p> -<pre> -LogFormat "%h %l %u %t %D \"%r\" %&gt;s %b" common -CustomLog logs/access_log common -</pre> - -<p> -The first line defines the format <code>common</code>, with the remote host -specified by <code>%h</code>. The second line sends access information to a log -file <code>logs/access_log</code>, using the previously defined format -<code>common</code>. -<p> -Furtunately, Apache's <code>LogFormat</code> allows one to log contents of -headers. By replacing the <code>%h</code> with <code>%{X-Real-IP}i</code>, the desired -information is sent to the log. Therefore, normally you can simply -redefine the <code>common</code> format to -<p> -<pre> -LogFormat "%{X-Real-IP}i %l %u %t %D \"%r\" %&gt;s %b" common -</pre> - -<p> -<a name="l62"></a> -<h3>5.7: Debugging network traffic</h3> +<a name="l64"></a> +<h3>5.8: Debugging network traffic</h3> <a name="tips/debugging"></a> Incase the traffic between client and backend must be debugged, the statement <code>trafficlog</code> <em>filename</em> can @@ -2531,10 +2455,10 @@ Summarizing, the throughput times of a client-back end connection analyze the output and to compute round trip times. Such scripts are not (yet) included in Crossroads. <p> -<a name="l63"></a> -<h3>5.8: IP filtering: Limiting Access by Client IP Address</h3> -<a name="tips/ipfiltering"></a><a name="l64"></a> -<strong>5.8.1: General Examples</strong> +<a name="l65"></a> +<h3>5.9: IP filtering: Limiting Access by Client IP Address</h3> +<a name="tips/ipfiltering"></a><a name="l66"></a> +<strong>5.9.1: General Examples</strong> <p> The directives <code>allowfrom</code>, <code>denyfrom</code>, <code>allowfile</code> and <code>denyfile</code> can be used to instruct Crossroads to specifically allow @@ -2570,8 +2494,8 @@ with 192.168.1. The specifier <code>192.168.1/24</code> 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. <p> -<a name="l65"></a> -<strong>5.8.2: Using External Files</strong> +<a name="l67"></a> +<strong>5.9.2: Using External Files</strong> <p> The directives <code>allowfile</code> and <code>denyfile</code> allow you to specify IP addresses in external files. The Crossroads configuration states @@ -2602,8 +2526,8 @@ is running, you may edit <code>/tmp/allow.txt</code>, and then issue <code>killa -1 crossroads</code>. The new contents of <code>/tmp/allow.txt</code> will be reloaded. <p> -<a name="l66"></a> -<strong>5.8.3: Mixing Directives</strong> +<a name="l68"></a> +<strong>5.9.3: Mixing Directives</strong> <p> Crossroads allows to mix all directives in one service description. However, some mixes are less meaningful than others. It's @@ -2669,255 +2593,491 @@ 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. <p> -<a name="l67"></a> -<h3>5.9: Configuration examples</h3> -<a name="tips/examples"></a> -<a name="l68"></a> -<strong>5.9.1: A load balancer for three webserver back ends</strong> +<a name="l69"></a> +<h3>5.10: Using an external program to dispatch</h3> <a name="externalhandler"></a> +<a name="tips/externalhandler"></a>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. <p> -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. +<a name="l70"></a> +<strong>5.10.1: Configuring the external handler</strong> +<p> +First, the <code>dispatchmode</code> statement needs to inform Crossroads that +an external program will do the job. The syntax is: <code>dispatchmode +externalhandler</code> <em>program arguments</em>. The <em>program</em> must point to +an executable program that will be started by Crossroads. The +specifier <em>arguments</em> can be anything you want; those will be the +arguments to your dispatch helper. You use the following special +format specifiers in the argument list: +<p> +<ul> + <li> <code>%a</code> is the availability of the current back end, when + a current back end is established; + <li> <code>%1a</code> is the availability of the first back end (0 when + unavailable, 1 if available); <code>%2a</code> is the availability of + the second back end, and so on; + <li> <code>%b</code> is the name of the current back end, when one is + established; + <li> <code>%1b</code> is the name of the first back end, <code>%2b</code> of the + second back end, and so on; + <li> <code>%e</code> is the count of seconds since start of epoch + (January 1st 1970 GMT); + <li> <code>%r</code> is the IP address of the client that requests a + connection and for whom the external dispatcher should compute + a back end; + <li> <code>%s</code> is the name of the current service that the client + connected to; + <li> <code>%t</code> is the current local time in ASCII format, in + <em>YYYY-MM-DD/hhh:mm:ss</em>; + <li> <code>%T</code> is the current GMT time in ASCIII format; + <li> <code>%v</code> is the Crossroads version; + <li> Any other chararacter following a <code>%</code> sign is taken + literally; e.g. <code>%z</code> is just a z.</ul> +<p> +Note that the format specifiers such as <code>%b</code> 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, so at +the time of calling, <code>%b</code> is undefined). +<p> +<a name="l71"></a> +<strong>5.10.2: Writing the external handler</strong> +<p> +The external handler is activated using the arguments that are +specified in /etc/crossroads.conf. The external handler can do +whatever it wants, but ultimately, it must write a back end name on +its <em>stdout</em>. Crossroads reads this, and if the back end is +available, uses that back end for the connection. +<p> +<a name="l72"></a> +<strong>5.10.3: Examples of external handlers</strong> +<p> +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 +<code>etc/</code>. 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. +<p> +<p><strong>Round-robin dispatching</strong><br> +<p> +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. +<p> +The Crossroads configuration is shown below: <p> <pre> -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. */ +service test { + port 8001; verbosity on; + revivinginterval 5; - /* 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; + 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; + } +} +</pre> + +<p> +The relevant <code>dispatchmode</code> statement invokes the external program +<code>dispatcher-roundrobin</code> with four arguments: the name of the first +back end (<code>testone</code>), its availability (0 or 1), the name of the +second back end (<code>testtwo</code>) and its availability (0 or 1). +<p> +The external handler, which is also included in the Crossroads +distribution, is shown below. It is a Perl script. +<p> +<pre> +#!/usr/bin/perl - /* 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; +use strict; - /* 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; +# 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. - /* 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; +# 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 - /* 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; +# Logging +# ------- +sub msg { + return if ($log eq '/dev/null' or $log eq ''); + open (my $of, "&gt;&gt;$log") or return; + print $of (scalar(localtime()), ' ', @_); +} + +# Read the last used back end +# --------------------------- +sub readlast() { + my $ret; + + if (open (my $if, $statefile)) { + $ret = &lt;$if&gt;; + chomp ($ret); + close ($if); + msg ("Last used back end: $ret\n"); + return ($ret); } + msg ("No last-used back end (yet)\n"); + return (undef); +} - /* The second one: */ - backend www_backend_2 { - /* Server and port */ - server httpserver2; - port 9011; +# Write back the last used back end, reply to Crossroads and stop +# --------------------------------------------------------------- +sub reply ($) { + my $last = shift; - /* Verbosity of reporting when this back end is active */ - verbosity on; + if (open (my $of, "&gt;$statefile")) { + print $of ("$last\n"); + } + print ("$last\n"); + exit (0); +} - /* Decay */ - decay 10; +# Main starts here +# ---------------- - /* This back end is twice as weak as the first one */ - weight 2; +# Collect the cmdline arguments. We expect pairs of backend-name / +# backend-availablility, and we'll store only the available ones. +msg ("Dispatch request received\n"); +my @backend; +for (my $i = 0; $i &lt;= $#ARGV; $i += 2) { + push (@backend, $ARGV[$i]) if ($ARGV[$i + 1]); +} +msg ("Available back ends: @backend\n"); - /* 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; - } +# 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]\n"); + reply ($backend[0]); +} - /* 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; +# There **was** a last back end. Try to match it in the list, +# then return the next-in-line. +for (my $i = 0; $i &lt; $#backend; $i++) { + if ($last eq $backend[$i]) { + msg ("Returning next back end ", $backend[$i + 1], "\n"); + reply ($backend[$i + 1]); } } + +# No luck.. run back to the first one. +msg ("Returning first back end $backend[0]\n"); +reply ($backend[0]); </pre> <p> -<a name="l69"></a> -<strong>5.9.2: An HTTP forwarder when travelling</strong> +The working of the script is basically as follows: <p> -As another example, here's my /etc/crossroads.conf 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. +<ul> + <li> The argument list is scanned. Back ends that are + available are collected in an array <code>@backend</code>. <p> -Here's how it used to be before crossroads: +<li> The script queries a state file <code>/tmp/rr.last</code>. If a + back end name occurs there, then the next back end is looked + up in <code>@backend</code> and returned to Crossroads. If no last back + is unknown or can't be matched, then the first available back + end (first element of <code>@backend</code>) is returned to Crossroads. +<p> +<li> Informing Crossroads is done via the subroutine + <code>reply()</code>. This code writes the selected back end to file + <code>/tmp/rr.last</code> (for future usage) and prints the back end + name to <em>stdout</em>. +<p> +<li> The script logs its actions to a file + <code>/tmp/exthandler.log</code>. This log file can be inspected for + the script's actions.</ul> +<p> +<p><strong>Dispatching by the client IP address</strong><br> +<p> +The following example shows a useful real-life situation that +illustrates how dispatching by client IP address works. <strong>Note that</strong> +as of Crossroads 1.31, <code>dispatchmode byclientip</code> 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. (Incidentally, the <code>dispatchmode</code> +<code>byclientip</code> was modeled after the shown script. The functionality +proved so useful that it was embedded into Crossroads.) +<p> +Our hypothetical dispatching situation is as follows: <p> <ul> - <li> At home, I would surf through a squid proxy on my local - machine. The browser proxy setting is then - <code>http://localhost:3128</code>. + <li> 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; <p> -<li> 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 - <code>http://localhost:3129</code>. +<li> 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; <p> -<li> At a customer's location I need the proxy - <code>http://10.120.34.113:8080</code>, because they have configured it - so. +<li> Client PC's have their distinct IP addresses, which + distinguish them. <p> -<li> And in yet other instances, I use a HTTP diagnostic tool - <a href="http://www.xk72.com/charles">Charles</a> - 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 - <code>http://localhost:8888</code>.</ul> +<li> 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.</ul> +<p> +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: +the potential delay due to the calling of an external +handler won't even be noticed. Remote Desktop is a network service where +the connection time isn't critical; users won't notice a slightly +larger connection time due to the fact that Crossroads invokes an +external program. We expect only a few (albeit lengthy) TCP connections. +<p> +The approach to the solution of this problem uses several external +program hooks: +<p> +<ul> + <li> 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. + <li> An external hook <code>onstart</code> will be responsible for + updating the internal administration; i.e., to flag a back end + as 'occupied'. + <li> The external hooks <code>onfailure</code> and <code>onend</code> 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.</ul> +<p> +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). +<p> +<pre> +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; + } +} +</pre> + <p> -Here's how it works with a crossroads configuration: +Depending on the dispatcher stage, the exernal handler <code>rdp-helper</code> +is invoked in different ways: <p> -<ul> - <li> I have configured my browsers to use - <code>http://localhost:8080</code> as the proxy. For all situations. +<dl> + <p><dt><strong>During dispatching</strong><dd> the helper is called to suggest a back + end. The arguments are an action indicator <code>dispatch</code>, 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. <p> -<li> I use the following crossroads configuration, and let - crossroads figure out which proxy backend works, and which - doesn't. Note two particularities: +<p><dt><strong>During connection start</strong><dd> the helper will be invoked to + inform it of the start of a connection, given a client IP + address. <p> -<ul> - <li> The statement <code>dispatchmode byorder</code>. 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. +<p><dt><strong>When a connection terminates</strong><dd> the helper will be invoked + to inform it that the connection has ended.</dl> <p> -<li> The statement <code>bindto 127.0.0.1</code> makes sure - that requests from other interfaces than loopback - won't get serviced.</ul> +Here's the external handler as Perl script. It uses the module +<code>GDBM_File</code> 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.) <p> <pre> -service HttpProxy { - port 8080; - bindto 127.0.0.1; - verbosity on; - dispatchmode byorder; - revivinginterval 15; +#!/usr/bin/perl - backend Charles { - server localhost:8888; - verbosity on; +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, "&gt;&gt;$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.\n"); + print ("$b\n"); + exit (0); +} + +# Is a value in an array +# ---------------------- +sub inarray { + my $val = shift; + for my $other (@_) { + return (1) if ($other eq $val); } + return (0); +} - backend CustomerProxy { - server 10.120.34.113:8080; - verbosity on; +# A connection is starting +# ------------------------ +sub start { + my ($ip, $stamp, $backend) = @_; + msg ("Logging START of connection for IP $ip on stamp $stamp, ", + "back end $backend\n"); + $db{$ip} = "$backend:$stamp"; +} + +# A connection has ended +# ---------------------- +sub end { + my $ip = shift; + msg ("Logging END of connection for IP $ip\n"); + $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\n"); + + # 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 &lt; $#_; $i += 3) { + if ($_[$i + 1] != 0) { + push (@backends, $_[$i]); + push (@weights, $_[$i + 2]); + msg ("Candidate back end: $_[$i] with weight ", $_[$i + 2], "\n"); + } } - backend SshTunnel { - server localhost:3129; + # 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\n"); + if ($stamp &lt; $last_stamp + $timeout) { + msg ("Timeout not yet exceeded, this may be a reconnect\n"); + # 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\n"); + reply ($last_backend); + } else { + msg ("Last used back end isn't free, suggesting a new one\n"); + } + } else { + msg ("Timeout exceeded, suggesting a new back end\n"); + } + } else { + msg ("Np preveious connection data, suggesting a new back end\n"); } - backend LocalSquid { - server localhost:3128; + my $bestweight = -1; + my $bestbackend; + for (my $i = 0; $i &lt;= $#weights; $i++) { + if ($bestweight == -1 or $bestweight &gt; $weights[$i]) { + $bestweight = $weights[$i]; + $bestbackend = $backends[$i]; + } } + + msg ("Best back end: $bestbackend (given weight $bestweight)\n"); + reply ($bestbackend); } -</pre> -</ul> -<p> -As a final note, the commandline argument <code>tell</code> 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 <code>SshTunnel</code> -and <code>LocalSquid</code> are both active, then <code>crossroads tell httpproxy -sshtunnel down</code> will 'take down' the back end <code>SshTunnel</code> -- and -will automatically cause crossroads to switch to <code>LocalSquid</code>. -<p> -<a name="l70"></a> -<strong>5.9.3: SSH login with enforced idle logout</strong> -<p> -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. -<p> -Note the usage of the -<code>connectiontimeout</code> directive. This makes sure that users are logged -out after 10 minutes of inactivity. Note also the <code>maxconnections</code> -setting, this makes sure that no more than 10 concurrent logins occur. -<p> -<pre> -service Ssh { - port 22; - backlog 5; - maxconnections 10; - connectiontimeout 600; - backend TrueSshDaemon { - server localhost:2222; - } + +# Main starts here +# ---------------- +msg ("Start of run, attaching GDBM database '$cdb'\n"); +tie (%db, 'GDBM_File', $cdb, &amp;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\n"); + exit (1); } </pre> <p> -<a name="l71"></a> -<h3>5.10: Linux and ip_conntrack_max</h3> +<a name="l73"></a> +<h3>5.11: Linux and ip_conntrack_max</h3> <a name="tips/ipconntrackmax"></a>The kernel value of <code>ip_conntrack_max</code> 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: @@ -2953,8 +3113,8 @@ out yourself. Note however that each count will cause the kernel to reserve 350 bytes. So if you set <code>ip_conntrack_max</code> to 100.000, then you're already taking 33.3Mb off the total available memory. <p> -<a name="l72"></a> -<h3>5.11: Marking back ends as bad after more than one try</h3> +<a name="l74"></a> +<h3>5.12: Marking back ends as bad after more than one try</h3> <a name="tips/retries"></a>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, @@ -2998,8 +3158,8 @@ retry connecting with a small one-second delay in between. A high <code>retries</code> number means also lots of one-second delays, in which time a client is kept waiting. <p> -<a name="l73"></a> -<h3>5.12: Scripting Crossroads' back end availability</h3> +<a name="l75"></a> +<h3>5.13: Scripting Crossroads' back end availability</h3> <a name="tips/scripting"></a>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 <code>revivinginterval</code> statement of a service @@ -3161,8 +3321,8 @@ done The further implementation of such a mini-daemon that fires up <code>healthcheck</code> is left to the reader. <p> -<a name="l74"></a> -<h3>5.13: Rendering Crossroads' status in a web page</h3> <a name="xmlstatus"></a> +<a name="l76"></a> +<h3>5.14: 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. @@ -3231,8 +3391,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="l75"></a> -<h3>5.14: Crossroads and DNS caching</h3> +<a name="l77"></a> +<h3>5.15: 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: @@ -3255,13 +3415,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="l76"></a> +<a name="l78"></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="l77"></a> +<a name="l79"></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: @@ -3289,7 +3449,7 @@ service HttpProxy { </pre> <p> -<a name="l78"></a> +<a name="l80"></a> <strong>6.1.1: Results</strong> <p> The results of this test are that crossroads causes a negligible @@ -3312,7 +3472,7 @@ sys 0m0.230s </pre> <p> -<a name="l79"></a> +<a name="l81"></a> <strong>6.1.2: Discussion</strong> <p> The above shown results are quite favorable to crossroads. However, @@ -3344,7 +3504,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="l80"></a> +<a name="l82"></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 @@ -3358,7 +3518,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="l81"></a> +<a name="l83"></a> <strong>6.2.1: Environment</strong> <p> On the balancer, LVS was run on port 80, its forwarding set up for two @@ -3389,7 +3549,7 @@ service http { </pre> <p> -<a name="l82"></a> +<a name="l84"></a> <strong>6.2.2: Tests and results</strong> <p> In the first test, ports 80 and 81 on the balancer were 'bombed' with @@ -3468,9 +3628,9 @@ 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="l83"></a> +<a name="l85"></a> <h2>7: Compiling and Installing</h2> <a name="installation"></a> -<a name="compiling"></a><a name="l84"></a> +<a name="compiling"></a><a name="l86"></a> <h3>7.1: Prerequisites</h3> <p> The creation of crossroads requires: @@ -3487,7 +3647,7 @@ 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="l85"></a> +<a name="l87"></a> <h3>7.2: Compiling and installing</h3> <p> <ul> @@ -3543,7 +3703,7 @@ crossroads, follow these steps. <p> </ul> <p> -<a name="l86"></a> +<a name="l88"></a> <h3>7.3: Configuring crossroads</h3> <p> Now that the binary is available on your system, you need to create a @@ -3592,13 +3752,13 @@ 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="l87"></a> +<a name="l89"></a> <h3>7.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="l88"></a> +<a name="l90"></a> <strong>7.4.1: SysV Style Startup</strong> <p> On SysV style systems, there's a startup script directory @@ -3640,7 +3800,7 @@ 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="l89"></a> +<a name="l91"></a> <strong>7.4.2: BSD Style Startup</strong> <p> On BSD style systems, daemons are booted directly from <code>/etc/rc</code> and diff --git a/doc/crossroads.pdf b/doc/crossroads.pdf Binary files differ. diff --git a/doc/main/conf/headerinspection.yo b/doc/main/conf/headerinspection.yo @@ -0,0 +1,13 @@ +conf(headerinspection - are all HTTP headers inspected) + (The tt(headerinspection) directive defines whether Crossroads +must inspect all HTTP headers that are seen on one TCP connection, or +only the first ones. There are two possible values for this directive: +tt(deep) and tt(shallow). In tt(deep) mode, all information that is +seen on the TCP link is monitored +and parsed, and all HTTP header blocks are analyzed and subject to +directives such as tt(addclientheader). In tt(shallow) mode, only the +first header block that the server sends, and the first header block +that forms the server's answer, are analyzed.) + (tt(headerinspection) em(specifier), where em(specifier) is +tt(deep) or tt(shallow)) + (tt(deep)) diff --git a/doc/main/conf/shmkey.yo b/doc/main/conf/shmkey.yo @@ -14,4 +14,5 @@ conf(shmkey - Shared Memory Access) and as long as each invocation of crossroads uses it.) (tt(shmkey) em(number)) (0, which means that crossroads will 'guess' its - own key, based on the service name.) -\ No newline at end of file + own key, based on the service name.) + diff --git a/doc/main/config.yo b/doc/main/config.yo @@ -52,6 +52,26 @@ service web { The tt(port) statement is then read as tt(port 80). +The statement tt(#define) can also be very nicely used when trying out +Crossroads configurations. Crossroads has a statement tt(verbosity) +tt(true) that causes debugging information to be logged. Once a +configuration has proven to work, you'll most likely want +tt(verbosity) tt(false) so that overhead due to logging is +avoided. This can be easily implemented using tt(#define): + +verb(\ +/* Set DEBUG to true or false; + * true is for testing purposes, + * false is for production */ +#define DEBUG true + +service web { + verbosity DEBUG; + . + . /* More statements follow here */ + . +}) + confsubsect(Keywords, numbers, identifiers, generic strings) @@ -118,8 +138,9 @@ redef(conf)(4)(\ enddit()) -includefile(conf/type) includefile(conf/port) +includefile(conf/type) +includefile(conf/headerinspection) includefile(conf/bindto) includefile(conf/verbose) includefile(conf/dispatchmode) diff --git a/doc/main/tips.yo b/doc/main/tips.yo @@ -2,15 +2,15 @@ The following sections elaborate on the directives as described in section ref(config) to illustrate how crossroads works and to help you achieve the "optimal" balancing configuration. +subsect(Configuration examples) +includefile(tips/examples) + subsect(How back ends are selected in load balancing) label(howselected) includefile(tips/howselected) subsect(Throttling the number of concurrent connections) includefile(tips/throttling) -subsect(Using an external program to dispatch) label(externalhandler) -includefile(tips/externalhandler) - subsect(TCP Session Stickiness) includefile(tips/tcpstickiness) @@ -20,14 +20,17 @@ includefile(tips/httpstickiness) subsect(Passing the client's IP address) includefile(tips/clientip) +subsect(Deep or shallow HTTP header inspection) +includefile(tips/deeporshallow) + subsect(Debugging network traffic) includefile(tips/debugging) subsect(IP filtering: Limiting Access by Client IP Address) includefile(tips/ipfiltering) -subsect(Configuration examples) -includefile(tips/examples) +subsect(Using an external program to dispatch) label(externalhandler) +includefile(tips/externalhandler) subsect(Linux and ip_conntrack_max) includefile(tips/ipconntrackmax) diff --git a/doc/main/tips/clientip.yo b/doc/main/tips/clientip.yo @@ -11,6 +11,9 @@ configuration must state the following: itemization( it() The service type must be tt(http), and not tt(any); + it() Make sure that the tt(headerinspection) is tt(deep) (or that + there is no tt(headerinspection) statement, since tt(deep) is + the default, see section ref(tips/deeporshallow)); it() In the back end definition, the following statement must occur: nl() tt(addserverheader "X-Real-IP: %r";) nl() diff --git a/doc/main/tips/deeporshallow.yo b/doc/main/tips/deeporshallow.yo @@ -0,0 +1,103 @@ +The service-level directive tt(headerinspection) defines which HTTP +headers Crossroads will analyze. Often, several HTTP requests and +responses will be served over one network +link. Browsers and servers will try to keep a TCP link open so that it +may be re-used; this is a measure to increase efficiency and to shorten load +times of pages. E.g., a typical HTML page +will require a style sheet and a few images - and these can be +retrieved over the same link that originally served the HTML page. + +Re-using the TCP link occurs more often than not. It is the default in +HTTP/1.1 (unless tt(Connection: close) is specified as one of the HTTP +headers). The older HTTP protocol, HTTP/1.0, by default passes just +one request and response over a TCP link, after which the link is +closed (unless tt(Connection: keep-alive) is specified as one of the +HTTP headers). + +If you define your service as tt(type http), then by default +Crossroads will inspect all HTTP headers that it sees: not only the +first browser request and server answer, but also subsequent requests +and answers that travel over the same link. This is called 'deep +inspection mode', in which Crossroads applies +directives such as tt(addclientheader) to all header +blocks. Inspecting the full TCP stream to catch header blocks can be +resource consuming. You can optionally make Crossroads's resource +consumption 'lighter' by instructing it to inspect only the first +HTTP header block, and to simply pass-through over all subsequent information +(which might well include next header blocks of a re-used TCP +connection) This is done using the directive tt(headerinspection): + +verb(\ +service web { + type http; + headerinspection shallow; + backend a { .... } + backend b { .... } +}) + +The situations where tt(shallow) mode can be used, depends on what you +need to do: + +itemization( + it() tt(shallow) mode can be used when the inspection and + modification of the first HTTP header block suffices. For example, + HTTP session stickiness is a good example: + +verb(\ +service web { + type http; + headerinspection shallow; + backend a { + server 10.1.1.1:80; + stickycookie "BalancerID=1"; + addclientheader "Set-Cookie: BalancerID=1"; + } + . + . other back ends are defined here + . +}) + + In this case, Crossroads will inspect only the first header block that + the client sends for the presence of a cookie tt(BalancerID). If the + cookie has value 1, then the request will be routed to back end + tt(a). Similarly, Crossroads will inspect only the first header block + that the server sends, and will inject a tt(Set-Cookie) + instruction. + + In this example, deep mode is not necessary because Crossroads + will use the first header that the client sends to route the + information to a given back end. + If more than one HTTP transactions follow over + the same TCP link, then by definition the link will go to the + same back end - even without inspecting all HTTP headers that + follow the first ones. + + it() tt(deep) mode is necessary in situations where all header + blocks must be inspected and modified. E.g., if you want to hide your + HTTP server identification, you might use: + +verb(\ +service web { + type http; + headerinspection deep; + backend a { + server 10.1.1.1:80; + setclientheader "Server: MyWebServer"; + } + . + . other back ends are defined here + . +}) + + Here, all HTTP header blocks that come from the server will be parsed, + and tt(Server) headers will be overwritten. + In a similar vein, if you want to pass the client's IP address, you + will also need deep mode. + + In these examples, tt(shallow) mode is not usable, because the + outbound header modifications should apply to all headers of a + given series. Imagine that one would use tt(shallow) mode + here: then, in a series of 5 HTTP transactions that pass over + the same TCP link, only the first transaction would hide the + HTTP server signature. All subsequent transactions would still + show the HTTP server signature to the world.) diff --git a/doc/main/tips/externalhandler.yo b/doc/main/tips/externalhandler.yo @@ -10,14 +10,15 @@ an external program will do the job. The syntax is: tt(dispatchmode externalhandler) em(program arguments). The em(program) must point to an executable program that will be started by Crossroads. The specifier em(arguments) can be anything you want; those will be the -arguments to Crossroads. You can however use the following special -format specifiers: +arguments to your dispatch helper. You use the following special +format specifiers in the argument list: INCLUDEFILE(formattable) Note that the format specifiers such as tt(%b) 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). +current back end yet (the job of the handler is to supply one, so at +the time of calling, tt(%b) is undefined). subsubsect(Writing the external handler) @@ -188,9 +189,11 @@ illustrates how dispatching by client IP address works. bf(Note that) as of Crossroads 1.31, tt(dispatchmode byclientip) 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. +modes, aided by external helpers. (Incidentally, the tt(dispatchmode) +tt(byclientip) was modeled after the shown script. The functionality +proved so useful that it was embedded into Crossroads.) -The situation is as follows: +Our hypothetical dispatching situation is as follows: itemization( it() Crossroads is used as a single-address point to forward @@ -202,7 +205,7 @@ itemization( they had worked on previously; it() Client PC's have their distinct IP addresses, which - distinguishes them. + distinguish them. it() Of four windows systems, two are large servers, and two are small ones. We'll want to assign large servers to clients @@ -211,15 +214,11 @@ itemization( 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: - -itemization( - it() A suitable dispatch mode isn't yet available in - Crossroads, but can be easily coded in an external handler; - - it() 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.) +the potential delay due to the calling of an external +handler won't even be noticed. Remote Desktop is a network service where +the connection time isn't critical; users won't notice a slightly +larger connection time due to the fact that Crossroads invokes an +external program. We expect only a few (albeit lengthy) TCP connections. The approach to the solution of this problem uses several external program hooks: diff --git a/doc/main/tips/httpstickiness.yo b/doc/main/tips/httpstickiness.yo @@ -64,7 +64,10 @@ proceed as follows: itemization( it() At the level of a tt(service) description, set the type to - tt(http). + tt(http). + it() Furthermore, set the tt(headerinspection) to tt(shallow) + (unless of course you also want to modify other HTTP headers, + see section ref(tips/deeporshallow)). it() At the level of each back end description, configure the tt(stickycookie) and a tt(addclientheader) directives.) @@ -89,6 +92,7 @@ verb(\ service www { port 80; type http; + headerinspection shallow; revivinginterval 15; dispatchmode byconnections; diff --git a/doc/man/crossroads.yo b/doc/man/crossroads.yo @@ -42,7 +42,12 @@ manpageoptions() it() bf(-b): Writes a binary representation of the configuration to em(stdout). For debugging only. - + + it() bf(-B) em(size): Sets the size of network buffers. Larger + buffers will mean a less number of tt(read()) or + tt(write()) operations, but a larger memory + footprint. Usually the default value will do fine. + it() bf(-C): Writes the compile time configuration to em(stdout) and stops. Useful when submitting bug reports. @@ -104,4 +109,4 @@ manpagebugs() manpageauthor() itemization( it() Author: AUTHORNAME() - it() Maintainer: MAINTAINERNAME() MAINTAINEREMAIL()) -\ No newline at end of file + it() Maintainer: MAINTAINERNAME() MAINTAINEREMAIL()) diff --git a/etc/Makefile.conf b/etc/Makefile.conf @@ -12,12 +12,13 @@ DEFS := -DDEFAULT_CONF='"$(DEFAULT_CONF)"' -DMAX_BACKEND=$(MAX_BACKEND) \ -DDNS_CACHETTL=$(DNS_CACHETTL) -DDEF_MAX=$(DEF_MAX) \ -DCONNECT_TIMEOUT=$(CONNECT_TIMEOUT) -DVER='"$(VER)/$(REVVER)"' \ -DSET_PROC_TITLE_BY_ARGV=$(SET_PROC_TITLE_BY_ARGV) \ - -DTCP_BUFSZ=$(TCP_BUFSZ) -DRETRY_WAIT=$(RETRY_WAIT) \ + -DDEFAULT_TCP_BUFSZ=$(DEFAULT_TCP_BUFSZ) -DRETRY_WAIT=$(RETRY_WAIT) \ -DREVVER='"$(REVVER)"' -DBINDIR='"$(BINDIR)"' \ -DPREFIX='"$(PREFIX)"' -DYEARS='"$(YEARS)"' \ -DEXTRALIBS='"$(EXTRALIBS)"' -DLIBS='"$(LIBS)"' \ -DAUTHORNAME='"$(AUTHORNAME)"' -DMAINTAINERNAME='"$(MAINTAINERNAME)"' \ -DMAINTAINEREMAIL='"$(MAINTAINEREMAIL)"' \ + -DDEFAULT_SPT_BUFSIZE=$(DEFAULT_SPT_BUFSIZE) \ $(shell $(BASE)/tools/c-conf -c $(BASE)/src/c-conf.cache \ ifheader01 malloc.h HAVE_MALLOC_H) \ $(shell $(BASE)/tools/c-conf -c $(BASE)/src/c-conf.cache \ @@ -33,4 +34,6 @@ DEFS := -DDEFAULT_CONF='"$(DEFAULT_CONF)"' -DMAX_BACKEND=$(MAX_BACKEND) \ $(shell $(BASE)/tools/c-conf -c $(BASE)/src/c-conf.cache \ libfunction01 vsyslog HAVE_VSYSLOG) \ $(shell $(BASE)/tools/c-conf -c $(BASE)/src/c-conf.cache \ - libfunction01 strcasestr HAVE_STRCASESTR) + libfunction01 strcasestr HAVE_STRCASESTR) \ + $(shell $(BASE)/tools/c-conf -c $(BASE)/src/c-conf.cache \ + libfunction01 setproctitle HAVE_SETPROCTITLE) 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.44 +VER = 1.45 # Years that Crossroads has been 'round. YEARS = 2005-2007 @@ -40,8 +40,9 @@ CONNECT_TIMEOUT = 2 # long should we wait between trying again? RETRY_WAIT = 1 -# The size of buffers for the copying of data between sockets. -TCP_BUFSZ = 10240 +# The default size of buffers for the copying of data between sockets. +# Can be overruled using the flag -B. +DEFAULT_TCP_BUFSZ = 5120 # The max size of the DNS cache (nr of entries). Crossroads will cache # gethostbyname() results until the max nr is exceeded; then the latest hits @@ -64,9 +65,15 @@ PREFIX = /usr/local # Installation directory for the binaries. BINDIR = $(PREFIX)/bin +# Default size of a commandline buffer. This is used in juggling the +# process name. If your headers define SPT_BUFSIZE then that will be used +# instead. +DEFAULT_SPT_BUFSIZE = 2048 + # If you're on Linux, then one can set the program title for 'ps' output # by modifying argv directly. If you're on Linux or if your system supports -# this too, then define as value 1. Otherwise set to zero. +# this too, then define as value 1. Otherwise set to zero. If your system +# has setproctitle(3) then that will be used instead. SET_PROC_TITLE_BY_ARGV = 1 # Set to some meaningful value if you're on Solaris and don't want to diff --git a/etc/Makefile.help b/etc/Makefile.help @@ -4,8 +4,10 @@ Make what? Choose: make local Local program construction; src/crossroads will be built - make install Locally built program is installed, see - etc/Makefile.def for the destination location + make install Locally built programs are installed, and the + manpages are installed, see etc/Makefile.def for + the destination location + make dbginstall Debugable programs are installed (for testing only) make documentation Creates documentation under doc/. Requires Yodl and pdflatex. make clean Cleanup of stale files diff --git a/etc/svnrev.txt b/etc/svnrev.txt @@ -1 +1 @@ -163 +170 diff --git a/src/Makefile b/src/Makefile @@ -16,6 +16,13 @@ install: prep BASE=$(BASE) make -C $$d install || exit 1; \ done +dbginstall: prep + for d in ${DIRS}; do \ + echo "Making install in $$d"; \ + echo BASE=$(BASE) make -C $$d dbginstall; \ + BASE=$(BASE) make -C $$d dbginstall || exit 1; \ + done + clean: for d in ${DIRS}; do \ echo "Making clean in $$d"; \ diff --git a/src/crossroads-daemon/Makefile b/src/crossroads-daemon/Makefile @@ -4,7 +4,10 @@ include $(BASE)/etc/Makefile.conf BIN = crossroads-daemon all: $(BIN) +dbginstall: all $(BINDIR)/$(BIN) + install: all $(BINDIR)/$(BIN) + strip $(BINDIR)/$(BIN) 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.44, a load balancer and fail over + * This file is part of Crosroads 1.45, 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.h b/src/crossroads.h @@ -1,9 +1,14 @@ /************************************************************************* - * This file is part of Crosroads 1.44, a load balancer and fail over + * This file is part of Crosroads 1.45, a load balancer and fail over * utility for TCP. Copyright (c) Karel Kubat, distributed under GPL. * Visit http://crossroads.e-tunity.com for information. *************************************************************************/ +/* Actually used commandline size. */ +#ifndef SPT_BUFSIZE +#define SPT_BUFSIZE DEFAULT_SPT_BUFSIZE +#endif + /* Includes. */ #include <ctype.h> @@ -87,6 +92,7 @@ typedef enum { /* Config parsing related */ cf_connectiontimeoutspec, cf_maxconnectionsspec, cf_typespec, + cf_inspectionspec, cf_dumpspec, cf_thruspec, cf_bindspec, @@ -170,6 +176,11 @@ typedef struct { /* Filtering information: */ unsigned mask; /* .. netmask */ } IpFilter; +typedef enum { /* HTTP header inspection mode */ + ins_deep, /* .. inspect all headers */ + ins_shallow, /* .. inspect only first */ +} HttpInspection; + /* The configuration in internal representation. When changing, remember * to change config_write() and config_read()! */ typedef struct { /* Service description */ @@ -187,6 +198,7 @@ typedef struct { /* Service description */ unsigned connectiontimeout; /* .. # secs for timeout handling */ unsigned maxconnections; /* .. max # of allowed connections */ Servicetype type; /* .. type of the service */ + HttpInspection inspection; /* .. header inspection mode */ char *allowfile; /* .. file with allowed IP filters */ char *denyfile; /* .. and denied */ int uid; /* .. UID to assume for system() */ @@ -316,6 +328,7 @@ EXTERN StateStringMap /* state/string map */ EXTERN Symtab *symtab; /* symbol table of #defines */ EXTERN int nsymtab; /* table size */ 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 FILE *yyin; /* config file handle */ diff --git a/src/crossroads/Makefile b/src/crossroads/Makefile @@ -4,14 +4,16 @@ include $(BASE)/etc/Makefile.conf BIN = crossroads all: $(BIN) +dbginstall: all $(BINDIR)/$(BIN) + install: all $(BINDIR)/$(BIN) + strip $(BINDIR)/$(BIN) clean: rm -f *.o $(BIN) $(BINDIR)/$(BIN): $(BIN) cp $(BIN) $(BINDIR)/$(BIN) - strip $(BINDIR)/$(BIN) main.o: main.c $(CC) -c -g -W -Wall $(DEFS) main.c diff --git a/src/crossroads/main.c b/src/crossroads/main.c @@ -1,5 +1,5 @@ /************************************************************************* - * This file is part of Crosroads 1.44, a load balancer and fail over + * This file is part of Crosroads 1.45, 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/Makefile b/src/lib/Makefile @@ -10,6 +10,7 @@ all: BASE=$(BASE) make grammar BASE=$(BASE) make $(LIB) +dbginstall: install install: all $(LIB): $(OBJ) diff --git a/src/lib/allocreporter.c b/src/lib/allocreporter.c @@ -1,5 +1,5 @@ /************************************************************************* - * This file is part of Crosroads 1.44, a load balancer and fail over + * This file is part of Crosroads 1.45, 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.44, a load balancer and fail over + * This file is part of Crosroads 1.45, 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.44, a load balancer and fail over + * This file is part of Crosroads 1.45, 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.44, a load balancer and fail over + * This file is part of Crosroads 1.45, 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.44, a load balancer and fail over + * This file is part of Crosroads 1.45, 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.44, a load balancer and fail over + * This file is part of Crosroads 1.45, 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.44, a load balancer and fail over + * This file is part of Crosroads 1.45, 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.44, a load balancer and fail over + * This file is part of Crosroads 1.45, 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.44, a load balancer and fail over + * This file is part of Crosroads 1.45, 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,16 +1,17 @@ /************************************************************************* - * This file is part of Crosroads 1.44, a load balancer and fail over + * This file is part of Crosroads 1.45, 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" void copysockets (int clientsock, int serversock) { - unsigned char buf[TCP_BUFSZ]; + unsigned char *buf = xmalloc (tcp_bufsz); /* Copy between client and server. Function net_copy() will * stop itself when either an error is seen, or when no more - * data are there. */ + * data are there. + * So there isn't even a reason to free(buf). */ while (1) - net_copy (clientsock, serversock, TCP_BUFSZ, buf); + net_copy (clientsock, serversock, tcp_bufsz, buf); } diff --git a/src/lib/createcommandlinespace.c b/src/lib/createcommandlinespace.c @@ -1,5 +1,5 @@ /************************************************************************* - * This file is part of Crosroads 1.44, a load balancer and fail over + * This file is part of Crosroads 1.45, 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.44, a load balancer and fail over + * This file is part of Crosroads 1.45, a load balancer and fail over * utility for TCP. Copyright (c) Karel Kubat, distributed under GPL. * Visit http://crossroads.e-tunity.com for information. *************************************************************************/ @@ -13,6 +13,7 @@ int log_facility = LOG_DAEMON; int shmperm = 0644; int dns_cachettl = DNS_CACHETTL; char *config_file = DEFAULT_CONF; +int tcp_bufsz = DEFAULT_TCP_BUFSZ; StateStringMap statestringmap[] = { { st_available, "available" }, diff --git a/src/lib/deallocreporter.c b/src/lib/deallocreporter.c @@ -1,5 +1,5 @@ /************************************************************************* - * This file is part of Crosroads 1.44, a load balancer and fail over + * This file is part of Crosroads 1.45, 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.44, a load balancer and fail over + * This file is part of Crosroads 1.45, 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.44, a load balancer and fail over + * This file is part of Crosroads 1.45, 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.44, a load balancer and fail over + * This file is part of Crosroads 1.45, 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.44, a load balancer and fail over + * This file is part of Crosroads 1.45, a load balancer and fail over * utility for TCP. Copyright (c) Karel Kubat, distributed under GPL. * Visit http://crossroads.e-tunity.com for information. *************************************************************************/ @@ -33,13 +33,13 @@ int fork_tcp_servicer (int to_backend) { program_stage = stage_serving; if (to_backend >= 0) - set_program_title ("Service %s: serving %s to %s", - client_ip, - activeservice->name, - activeservice->backend [current_backend].name); + setproctitle ("crossroads - Service %s: serving %s to %s", + client_ip, + activeservice->name, + activeservice->backend [current_backend].name); else - set_program_title ("Service %s: serving %s", - activeservice->name, client_ip); + setproctitle ("crossroads - Service %s: serving %s", + activeservice->name, client_ip); return (0); } diff --git a/src/lib/hashpjw.c b/src/lib/hashpjw.c @@ -1,5 +1,5 @@ /************************************************************************* - * This file is part of Crosroads 1.44, a load balancer and fail over + * This file is part of Crosroads 1.45, 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.44, a load balancer and fail over + * This file is part of Crosroads 1.45, a load balancer and fail over * utility for TCP. Copyright (c) Karel Kubat, distributed under GPL. * Visit http://crossroads.e-tunity.com for information. *************************************************************************/ @@ -14,8 +14,8 @@ static void copy (int src, int dst, int dir, int tot) { * This is the remaining count, or if the buffer is too small * for that, the buffer size. */ to_copy = tot - ncopied; - if (to_copy > TCP_BUFSZ) - to_copy = TCP_BUFSZ; + if (to_copy > tcp_bufsz) + to_copy = tcp_bufsz; buf = net_bufread (src, to_copy, &bytes, dir == dir_client_to_server); net_write (dst, buf, bytes, dir == dir_client_to_server); diff --git a/src/lib/httperror.c b/src/lib/httperror.c @@ -1,5 +1,5 @@ /************************************************************************* - * This file is part of Crosroads 1.44, a load balancer and fail over + * This file is part of Crosroads 1.45, 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.44, a load balancer and fail over + * This file is part of Crosroads 1.45, 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.44, a load balancer and fail over + * This file is part of Crosroads 1.45, 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.44, a load balancer and fail over + * This file is part of Crosroads 1.45, 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.44, a load balancer and fail over + * This file is part of Crosroads 1.45, 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.44, a load balancer and fail over + * This file is part of Crosroads 1.45, 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.44, a load balancer and fail over + * This file is part of Crosroads 1.45, 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.44, a load balancer and fail over + * This file is part of Crosroads 1.45, 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.44, a load balancer and fail over + * This file is part of Crosroads 1.45, 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.44, a load balancer and fail over + * This file is part of Crosroads 1.45, 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.44, a load balancer and fail over + * This file is part of Crosroads 1.45, 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.44, a load balancer and fail over + * This file is part of Crosroads 1.45, 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.44, a load balancer and fail over + * This file is part of Crosroads 1.45, 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.44, a load balancer and fail over + * This file is part of Crosroads 1.45, 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.44, a load balancer and fail over + * This file is part of Crosroads 1.45, a load balancer and fail over * utility for TCP. Copyright (c) Karel Kubat, distributed under GPL. * Visit http://crossroads.e-tunity.com for information. *************************************************************************/ @@ -26,7 +26,8 @@ void http_serve (int clientsock) { * - Read back the server's response * - Apply all client-directed headers * - Send the server's response to the client - * - Redo from start; this might be a Keep-Alive connection + * - Redo from start; this might be a Keep-Alive connection. + * Alternatively, if deep inspection is off, go to cpio-thru mode. */ while (1) { @@ -99,19 +100,6 @@ void http_serve (int clientsock) { serverresp = http_header_new(); http_header_read (serverresp, serversock, dir_server_to_client); - /* According to RFC1616, we should convert chunked output - * from the server to one big message. - * We won't do that here, it breaks streaming. - * But we will close connections in the case of chunked transfer. */ - if (client_persisting && - http_header_val (serverresp, "transfer-encoding")) { - msg ("Service %s: Server is sending chunks, forcing singleshot", - activeservice->name); - server_persisting = 0; - http_header_setheader (serverresp, "Connection: close"); - http_header_setheader (serverresp, "Proxy-Connection: close"); - } - /* Put client-directed headers in place. */ for (i = 0; i < activeservice->backend[current_backend].naddclientheader; @@ -129,10 +117,10 @@ void http_serve (int clientsock) { http_header_appendheader (serverresp, activeservice->backend[current_backend].appendclientheader[i]); - /* According to RFC1616, we should convert chunked output - * from the server to one big message. - * We won't do that here, it breaks streaming. - * But we will close connections in the case of chunked transfer. */ + /* According to RFC1616, we should convert chunked output from + * the server to one big message. We won't do that here, it breaks + * streaming. But we will close connections in the case of chunked + * transfer. */ if (client_persisting && http_header_val (serverresp, "transfer-encoding")) { msg ("Service %s: Server is sending chunks, forcing singleshot", @@ -180,9 +168,15 @@ void http_serve (int clientsock) { activeservice->name); break; } - - msg ("Service %s: Analyzing following requests over same TCP link", - activeservice->name); + + if (activeservice->inspection == ins_deep) + msg ("Service %s: Will analyze following requests over " + "the same TCP link", activeservice->name); + else { + msg ("Service %s: Shallow analysis - won't analyze following " + "requests of the same TCP link", activeservice->name); + break; + } } /* We're done analyzing. If there's leftovers in the network buffers, @@ -209,5 +203,4 @@ void http_serve (int clientsock) { /* This doesn't return */ copysockets (clientsock, serversock); - } diff --git a/src/lib/httpserversocket.c b/src/lib/httpserversocket.c @@ -1,5 +1,5 @@ /************************************************************************* - * This file is part of Crosroads 1.44, a load balancer and fail over + * This file is part of Crosroads 1.45, a load balancer and fail over * utility for TCP. Copyright (c) Karel Kubat, distributed under GPL. * Visit http://crossroads.e-tunity.com for information. *************************************************************************/ @@ -32,11 +32,10 @@ int http_serversocket (HttpHeader *m, int *is_continuation) { current_backend = i; if ( (sock = backend_connect ()) >= 0 ) { *is_continuation = 1; - set_program_title ("Service %s: serving %s to %s", - activeservice->name, - client_ip, - activeservice->backend[current_backend] - .name); + setproctitle ("crossroads - Service %s: serving %s to %s", + activeservice->name, + client_ip, + activeservice->backend[current_backend].name); return (sock); } } @@ -66,10 +65,10 @@ int http_serversocket (HttpHeader *m, int *is_continuation) { if ( (sock = backend_connect ()) >= 0 ) { servicereport->backendstate[current_backend].sessions++; *is_continuation = 0; - set_program_title ("Service %s: serving %s to %s", - activeservice->name, - client_ip, - activeservice->backend[current_backend].name); + setproctitle ("Service %s: serving %s to %s", + activeservice->name, + client_ip, + activeservice->backend[current_backend].name); return (sock); } } diff --git a/src/lib/httpwrite.c b/src/lib/httpwrite.c @@ -1,5 +1,5 @@ /************************************************************************* - * This file is part of Crosroads 1.44, a load balancer and fail over + * This file is part of Crosroads 1.45, 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.44, a load balancer and fail over + * This file is part of Crosroads 1.45, 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.44, a load balancer and fail over + * This file is part of Crosroads 1.45, 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.44, a load balancer and fail over + * This file is part of Crosroads 1.45, 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.44, a load balancer and fail over + * This file is part of Crosroads 1.45, 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.44, a load balancer and fail over + * This file is part of Crosroads 1.45, 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.44, a load balancer and fail over + * This file is part of Crosroads 1.45, 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.44, a load balancer and fail over + * This file is part of Crosroads 1.45, 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.44, a load balancer and fail over + * This file is part of Crosroads 1.45, 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.44, a load balancer and fail over + * This file is part of Crosroads 1.45, 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.44, a load balancer and fail over + * This file is part of Crosroads 1.45, 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.44, a load balancer and fail over + * This file is part of Crosroads 1.45, 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.44, a load balancer and fail over + * This file is part of Crosroads 1.45, 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.44, a load balancer and fail over + * This file is part of Crosroads 1.45, a load balancer and fail over * utility for TCP. Copyright (c) Karel Kubat, distributed under GPL. * Visit http://crossroads.e-tunity.com for information. *************************************************************************/ @@ -288,60 +288,62 @@ static void yy_fatal_error YY_PROTO(( yyconst char msg[] )); *yy_cp = '\0'; \ yy_c_buf_p = yy_cp; -#define YY_NUM_RULES 78 -#define YY_END_OF_BUFFER 79 -static yyconst short int yy_accept[455] = +#define YY_NUM_RULES 81 +#define YY_END_OF_BUFFER 82 +static yyconst short int yy_accept[477] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 75, 75, 76, 76, 79, 56, 54, 55, 56, 53, - 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, - 52, 52, 52, 52, 52, 52, 52, 52, 52, 56, - 65, 66, 64, 65, 65, 63, 60, 59, 60, 70, - 68, 68, 67, 74, 73, 71, 72, 71, 78, 75, - 76, 77, 54, 57, 0, 53, 52, 52, 52, 52, - 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, - 52, 52, 51, 52, 50, 52, 52, 52, 52, 52, - 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, - - 0, 0, 0, 0, 61, 0, 62, 58, 67, 71, - 72, 71, 75, 76, 0, 3, 52, 52, 30, 52, - 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, - 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, - 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, - 52, 52, 52, 52, 52, 50, 0, 0, 52, 52, - 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, - 52, 52, 52, 52, 52, 52, 32, 52, 52, 52, - 52, 7, 6, 52, 52, 52, 52, 52, 52, 52, - 52, 52, 52, 52, 29, 52, 52, 52, 0, 0, - - 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, - 52, 52, 52, 16, 52, 52, 52, 52, 52, 38, - 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, - 52, 52, 52, 52, 52, 52, 52, 0, 0, 52, - 52, 52, 52, 52, 52, 5, 52, 52, 52, 52, - 22, 52, 52, 52, 52, 52, 52, 52, 37, 52, - 20, 52, 52, 52, 17, 52, 52, 52, 8, 52, - 52, 52, 52, 52, 15, 0, 0, 52, 52, 52, - 52, 52, 52, 9, 10, 52, 52, 52, 23, 52, - 52, 52, 52, 52, 52, 52, 36, 11, 52, 52, - - 4, 52, 52, 52, 52, 52, 52, 52, 12, 52, - 2, 0, 52, 52, 52, 52, 52, 52, 52, 52, - 52, 52, 49, 47, 52, 52, 52, 52, 52, 52, - 52, 52, 52, 52, 52, 52, 52, 52, 1, 52, - 52, 48, 46, 52, 52, 52, 52, 52, 52, 52, - 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, - 52, 52, 52, 52, 52, 52, 26, 52, 21, 52, - 52, 52, 52, 52, 52, 19, 52, 52, 52, 31, - 52, 34, 52, 52, 52, 52, 52, 52, 52, 52, - 35, 52, 52, 52, 52, 52, 52, 52, 27, 52, - - 52, 52, 52, 52, 52, 18, 52, 52, 52, 52, - 52, 39, 52, 52, 52, 52, 52, 24, 52, 52, - 52, 52, 52, 52, 33, 52, 52, 52, 52, 52, - 52, 14, 52, 52, 52, 40, 43, 52, 52, 52, - 25, 52, 41, 44, 52, 52, 52, 28, 52, 52, - 13, 42, 45, 0 + 78, 78, 79, 79, 82, 59, 57, 58, 59, 56, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 59, + 68, 69, 67, 68, 68, 66, 63, 62, 63, 73, + 71, 71, 70, 77, 76, 74, 75, 74, 81, 78, + 79, 80, 57, 60, 0, 56, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 54, 55, 53, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + + 55, 0, 0, 0, 0, 64, 0, 65, 61, 70, + 74, 75, 74, 78, 79, 0, 3, 55, 55, 33, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 53, + 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 31, 55, 55, 55, 55, + 55, 55, 35, 55, 55, 55, 55, 7, 6, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + + 55, 29, 55, 55, 55, 0, 0, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 16, 55, 55, 55, 55, 55, 55, 41, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 0, 0, 55, 55, + 55, 55, 55, 55, 5, 55, 55, 55, 55, 22, + 55, 55, 55, 55, 55, 55, 55, 55, 40, 55, + 20, 55, 55, 55, 17, 55, 55, 55, 55, 8, + 55, 55, 55, 55, 55, 15, 0, 0, 55, 55, + 55, 55, 55, 55, 9, 10, 55, 55, 55, 23, + + 55, 55, 55, 55, 55, 55, 55, 55, 39, 11, + 55, 55, 4, 55, 55, 32, 55, 55, 55, 55, + 55, 12, 55, 2, 0, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 52, 50, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 1, 55, 55, 51, 49, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 26, 55, 21, 55, 55, 55, 55, 55, 55, + 55, 19, 55, 55, 55, 34, 55, 37, 55, 55, + + 55, 55, 55, 55, 55, 55, 38, 55, 55, 55, + 55, 55, 55, 55, 55, 27, 55, 55, 55, 55, + 55, 55, 18, 55, 55, 55, 55, 55, 55, 42, + 55, 55, 55, 55, 55, 24, 55, 55, 55, 55, + 55, 55, 55, 36, 55, 55, 55, 55, 55, 55, + 55, 14, 55, 55, 55, 43, 46, 55, 55, 55, + 25, 55, 55, 44, 47, 55, 55, 55, 30, 28, + 55, 55, 13, 45, 48, 0 } ; static yyconst int yy_ec[256] = @@ -384,254 +386,262 @@ static yyconst int yy_meta[38] = 4, 4, 4, 4, 4, 4, 4 } ; -static yyconst short int yy_base[468] = +static yyconst short int yy_base[490] = { 0, - 0, 549, 35, 41, 46, 47, 55, 67, 79, 109, - 62, 74, 551, 550, 552, 556, 39, 556, 84, 540, - 0, 76, 108, 523, 105, 514, 534, 516, 532, 518, - 105, 517, 81, 111, 104, 513, 524, 523, 522, 124, - 556, 556, 556, 534, 531, 556, 556, 556, 527, 556, - 556, 556, 0, 556, 556, 68, 0, 130, 556, 99, - 0, 556, 103, 556, 533, 524, 0, 517, 509, 496, - 503, 514, 503, 131, 502, 80, 497, 501, 494, 500, - 492, 487, 0, 502, 132, 502, 490, 492, 112, 485, - 123, 491, 493, 485, 121, 485, 494, 482, 488, 479, - - 153, 490, 481, 501, 556, 498, 556, 556, 0, 152, - 0, 155, 161, 0, 501, 556, 148, 476, 0, 484, - 478, 483, 142, 467, 469, 475, 470, 481, 458, 465, - 464, 473, 460, 461, 472, 461, 472, 454, 455, 452, - 465, 452, 458, 453, 445, 151, 454, 460, 448, 455, - 455, 454, 442, 455, 449, 0, 449, 451, 442, 447, - 430, 437, 150, 431, 439, 434, 430, 441, 420, 438, - 419, 435, 439, 421, 422, 432, 0, 422, 431, 425, - 432, 0, 0, 418, 422, 410, 425, 154, 417, 422, - 421, 415, 405, 417, 0, 421, 407, 412, 410, 407, - - 408, 400, 409, 410, 400, 398, 397, 405, 396, 407, - 402, 401, 402, 0, 151, 386, 387, 389, 388, 0, - 389, 383, 386, 392, 387, 379, 378, 390, 383, 375, - 367, 366, 381, 378, 383, 368, 366, 370, 363, 376, - 360, 155, 163, 375, 371, 0, 364, 371, 357, 358, - 0, 355, 361, 357, 367, 368, 367, 354, 0, 348, - 0, 348, 351, 349, 0, 357, 356, 340, 0, 167, - 351, 355, 354, 168, 0, 351, 351, 341, 348, 341, - 337, 339, 344, 0, 0, 330, 344, 337, 0, 336, - 339, 331, 334, 335, 329, 334, 0, 0, 331, 335, - - 0, 323, 330, 320, 315, 317, 320, 316, 0, 311, - 556, 323, 309, 310, 320, 312, 314, 306, 312, 302, - 305, 304, 0, 0, 305, 310, 307, 311, 304, 303, - 293, 294, 295, 290, 288, 292, 286, 281, 556, 295, - 294, 0, 0, 296, 280, 284, 289, 284, 283, 281, - 285, 292, 274, 278, 277, 281, 280, 277, 271, 267, - 277, 270, 277, 276, 267, 274, 0, 264, 0, 259, - 272, 272, 261, 264, 254, 0, 266, 265, 260, 0, - 257, 0, 249, 265, 264, 246, 247, 249, 252, 255, - 0, 255, 244, 252, 255, 254, 249, 239, 0, 248, - - 247, 242, 241, 231, 235, 0, 235, 232, 228, 239, - 238, 0, 234, 235, 234, 233, 232, 0, 231, 230, - 217, 213, 227, 226, 0, 214, 213, 227, 226, 212, - 209, 0, 223, 207, 200, 0, 0, 175, 174, 157, - 0, 163, 0, 0, 153, 131, 105, 0, 68, 31, - 0, 0, 0, 556, 193, 197, 201, 205, 209, 213, - 48, 217, 221, 223, 47, 227, 231 + 0, 571, 35, 41, 46, 47, 55, 67, 79, 109, + 62, 74, 573, 572, 574, 578, 39, 578, 84, 562, + 0, 76, 108, 545, 105, 536, 556, 77, 555, 541, + 105, 540, 114, 115, 113, 536, 547, 546, 545, 141, + 578, 578, 578, 557, 554, 578, 578, 578, 550, 578, + 578, 578, 0, 578, 578, 68, 0, 95, 578, 99, + 0, 578, 103, 578, 556, 547, 0, 540, 532, 519, + 526, 537, 526, 134, 525, 136, 520, 524, 517, 523, + 532, 514, 509, 0, 524, 129, 524, 512, 514, 122, + 507, 136, 115, 516, 508, 142, 508, 517, 505, 511, + + 502, 164, 513, 504, 524, 578, 521, 578, 578, 0, + 153, 0, 165, 168, 0, 524, 578, 155, 499, 0, + 507, 501, 506, 149, 490, 492, 498, 493, 504, 489, + 480, 487, 486, 495, 482, 494, 482, 493, 482, 493, + 475, 476, 473, 486, 473, 479, 474, 466, 159, 474, + 474, 480, 468, 475, 475, 474, 462, 475, 469, 0, + 469, 471, 462, 467, 450, 457, 160, 451, 459, 454, + 450, 461, 440, 458, 439, 0, 455, 459, 441, 442, + 452, 451, 0, 441, 450, 444, 451, 0, 0, 437, + 441, 429, 444, 169, 436, 441, 434, 439, 433, 423, + + 435, 0, 439, 425, 430, 428, 425, 426, 418, 427, + 428, 418, 416, 415, 423, 414, 425, 420, 419, 420, + 0, 168, 404, 405, 407, 403, 405, 0, 406, 400, + 403, 409, 404, 396, 395, 407, 400, 392, 393, 383, + 382, 397, 394, 399, 384, 382, 386, 379, 392, 376, + 170, 163, 391, 387, 0, 380, 387, 373, 374, 0, + 371, 377, 373, 383, 384, 383, 374, 369, 0, 363, + 0, 363, 366, 364, 0, 372, 371, 355, 353, 0, + 161, 365, 369, 368, 176, 0, 365, 365, 355, 362, + 355, 351, 353, 358, 0, 0, 344, 358, 351, 0, + + 350, 353, 345, 348, 349, 343, 340, 347, 0, 0, + 344, 348, 0, 336, 343, 0, 333, 328, 330, 333, + 329, 0, 324, 578, 336, 322, 323, 333, 325, 327, + 319, 325, 315, 318, 317, 0, 0, 318, 323, 320, + 310, 323, 316, 315, 305, 306, 307, 302, 300, 304, + 298, 293, 578, 307, 306, 0, 0, 308, 292, 296, + 301, 296, 295, 293, 297, 304, 289, 285, 289, 288, + 292, 291, 288, 282, 278, 288, 281, 288, 287, 278, + 285, 0, 275, 0, 270, 283, 283, 272, 279, 274, + 264, 0, 276, 275, 270, 0, 267, 0, 259, 275, + + 274, 256, 257, 259, 262, 265, 0, 265, 265, 253, + 261, 264, 263, 258, 248, 0, 257, 256, 251, 250, + 240, 244, 0, 244, 236, 240, 236, 247, 246, 0, + 242, 243, 242, 241, 240, 0, 239, 238, 233, 224, + 220, 234, 233, 0, 221, 220, 234, 233, 219, 216, + 217, 0, 229, 213, 206, 0, 0, 179, 171, 148, + 0, 134, 111, 0, 0, 108, 88, 66, 0, 0, + 67, 31, 0, 0, 0, 578, 199, 203, 207, 211, + 215, 219, 48, 223, 227, 229, 47, 233, 237 } ; -static yyconst short int yy_def[468] = +static yyconst short int yy_def[490] = { 0, - 454, 1, 455, 455, 456, 456, 457, 457, 458, 458, - 459, 459, 460, 460, 454, 454, 454, 454, 454, 454, - 461, 461, 461, 461, 461, 461, 461, 461, 461, 461, - 461, 461, 461, 461, 461, 461, 461, 461, 461, 454, - 454, 454, 454, 462, 463, 454, 454, 454, 454, 454, - 454, 454, 464, 454, 454, 454, 465, 465, 454, 454, - 466, 454, 454, 454, 467, 454, 461, 461, 461, 461, - 461, 461, 461, 461, 461, 461, 461, 461, 461, 461, - 461, 461, 461, 461, 461, 461, 461, 461, 461, 461, - 461, 461, 461, 461, 461, 461, 461, 461, 461, 461, - - 454, 454, 454, 462, 454, 463, 454, 454, 464, 454, - 465, 465, 454, 466, 467, 454, 461, 461, 461, 461, - 461, 461, 461, 461, 461, 461, 461, 461, 461, 461, - 461, 461, 461, 461, 461, 461, 461, 461, 461, 461, - 461, 461, 461, 461, 461, 461, 461, 461, 461, 461, - 461, 461, 461, 461, 461, 461, 454, 454, 461, 461, - 461, 461, 461, 461, 461, 461, 461, 461, 461, 461, - 461, 461, 461, 461, 461, 461, 461, 461, 461, 461, - 461, 461, 461, 461, 461, 461, 461, 461, 461, 461, - 461, 461, 461, 461, 461, 461, 461, 461, 454, 454, - - 461, 461, 461, 461, 461, 461, 461, 461, 461, 461, - 461, 461, 461, 461, 461, 461, 461, 461, 461, 461, - 461, 461, 461, 461, 461, 461, 461, 461, 461, 461, - 461, 461, 461, 461, 461, 461, 461, 454, 454, 461, - 461, 461, 461, 461, 461, 461, 461, 461, 461, 461, - 461, 461, 461, 461, 461, 461, 461, 461, 461, 461, - 461, 461, 461, 461, 461, 461, 461, 461, 461, 461, - 461, 461, 461, 461, 461, 454, 454, 461, 461, 461, - 461, 461, 461, 461, 461, 461, 461, 461, 461, 461, - 461, 461, 461, 461, 461, 461, 461, 461, 461, 461, - - 461, 461, 461, 461, 461, 461, 461, 461, 461, 461, - 454, 454, 461, 461, 461, 461, 461, 461, 461, 461, - 461, 461, 461, 461, 461, 461, 461, 461, 461, 461, - 461, 461, 461, 461, 461, 461, 461, 461, 454, 461, - 461, 461, 461, 461, 461, 461, 461, 461, 461, 461, - 461, 461, 461, 461, 461, 461, 461, 461, 461, 461, - 461, 461, 461, 461, 461, 461, 461, 461, 461, 461, - 461, 461, 461, 461, 461, 461, 461, 461, 461, 461, - 461, 461, 461, 461, 461, 461, 461, 461, 461, 461, - 461, 461, 461, 461, 461, 461, 461, 461, 461, 461, - - 461, 461, 461, 461, 461, 461, 461, 461, 461, 461, - 461, 461, 461, 461, 461, 461, 461, 461, 461, 461, - 461, 461, 461, 461, 461, 461, 461, 461, 461, 461, - 461, 461, 461, 461, 461, 461, 461, 461, 461, 461, - 461, 461, 461, 461, 461, 461, 461, 461, 461, 461, - 461, 461, 461, 0, 454, 454, 454, 454, 454, 454, - 454, 454, 454, 454, 454, 454, 454 + 476, 1, 477, 477, 478, 478, 479, 479, 480, 480, + 481, 481, 482, 482, 476, 476, 476, 476, 476, 476, + 483, 483, 483, 483, 483, 483, 483, 483, 483, 483, + 483, 483, 483, 483, 483, 483, 483, 483, 483, 476, + 476, 476, 476, 484, 485, 476, 476, 476, 476, 476, + 476, 476, 486, 476, 476, 476, 487, 487, 476, 476, + 488, 476, 476, 476, 489, 476, 483, 483, 483, 483, + 483, 483, 483, 483, 483, 483, 483, 483, 483, 483, + 483, 483, 483, 483, 483, 483, 483, 483, 483, 483, + 483, 483, 483, 483, 483, 483, 483, 483, 483, 483, + + 483, 476, 476, 476, 484, 476, 485, 476, 476, 486, + 476, 487, 487, 476, 488, 489, 476, 483, 483, 483, + 483, 483, 483, 483, 483, 483, 483, 483, 483, 483, + 483, 483, 483, 483, 483, 483, 483, 483, 483, 483, + 483, 483, 483, 483, 483, 483, 483, 483, 483, 483, + 483, 483, 483, 483, 483, 483, 483, 483, 483, 483, + 476, 476, 483, 483, 483, 483, 483, 483, 483, 483, + 483, 483, 483, 483, 483, 483, 483, 483, 483, 483, + 483, 483, 483, 483, 483, 483, 483, 483, 483, 483, + 483, 483, 483, 483, 483, 483, 483, 483, 483, 483, + + 483, 483, 483, 483, 483, 476, 476, 483, 483, 483, + 483, 483, 483, 483, 483, 483, 483, 483, 483, 483, + 483, 483, 483, 483, 483, 483, 483, 483, 483, 483, + 483, 483, 483, 483, 483, 483, 483, 483, 483, 483, + 483, 483, 483, 483, 483, 483, 476, 476, 483, 483, + 483, 483, 483, 483, 483, 483, 483, 483, 483, 483, + 483, 483, 483, 483, 483, 483, 483, 483, 483, 483, + 483, 483, 483, 483, 483, 483, 483, 483, 483, 483, + 483, 483, 483, 483, 483, 483, 476, 476, 483, 483, + 483, 483, 483, 483, 483, 483, 483, 483, 483, 483, + + 483, 483, 483, 483, 483, 483, 483, 483, 483, 483, + 483, 483, 483, 483, 483, 483, 483, 483, 483, 483, + 483, 483, 483, 476, 476, 483, 483, 483, 483, 483, + 483, 483, 483, 483, 483, 483, 483, 483, 483, 483, + 483, 483, 483, 483, 483, 483, 483, 483, 483, 483, + 483, 483, 476, 483, 483, 483, 483, 483, 483, 483, + 483, 483, 483, 483, 483, 483, 483, 483, 483, 483, + 483, 483, 483, 483, 483, 483, 483, 483, 483, 483, + 483, 483, 483, 483, 483, 483, 483, 483, 483, 483, + 483, 483, 483, 483, 483, 483, 483, 483, 483, 483, + + 483, 483, 483, 483, 483, 483, 483, 483, 483, 483, + 483, 483, 483, 483, 483, 483, 483, 483, 483, 483, + 483, 483, 483, 483, 483, 483, 483, 483, 483, 483, + 483, 483, 483, 483, 483, 483, 483, 483, 483, 483, + 483, 483, 483, 483, 483, 483, 483, 483, 483, 483, + 483, 483, 483, 483, 483, 483, 483, 483, 483, 483, + 483, 483, 483, 483, 483, 483, 483, 483, 483, 483, + 483, 483, 483, 483, 483, 0, 476, 476, 476, 476, + 476, 476, 476, 476, 476, 476, 476, 476, 476 } ; -static yyconst short int yy_nxt[594] = +static yyconst short int yy_nxt[616] = { 0, 16, 17, 18, 17, 16, 16, 16, 16, 16, 19, 20, 16, 21, 22, 23, 24, 25, 26, 27, 21, 28, 21, 21, 21, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 21, 39, 21, 42, 43, 44, 63, 45, 63, 42, 43, 44, 46, 45, 48, 48, - 111, 67, 46, 49, 49, 50, 51, 52, 51, 453, + 112, 67, 46, 49, 49, 50, 51, 52, 51, 475, 50, 50, 50, 60, 55, 60, 50, 50, 51, 52, - 51, 110, 50, 50, 50, 60, 55, 60, 50, 54, + 51, 111, 50, 50, 50, 60, 55, 60, 50, 54, 54, 55, 56, 54, 54, 54, 54, 54, 54, 54, - 54, 64, 68, 65, 88, 128, 452, 110, 89, 69, + 54, 64, 68, 65, 81, 474, 473, 111, 111, 69, - 113, 70, 113, 71, 63, 129, 63, 90, 58, 54, + 114, 70, 114, 71, 63, 472, 63, 82, 58, 54, 54, 55, 56, 54, 54, 54, 54, 54, 54, 54, - 54, 72, 76, 84, 94, 101, 77, 101, 91, 73, - 85, 92, 95, 110, 150, 451, 78, 86, 58, 96, - 102, 93, 142, 74, 143, 103, 123, 124, 450, 136, - 137, 145, 151, 146, 101, 110, 101, 125, 110, 112, - 126, 138, 113, 159, 113, 165, 189, 205, 166, 102, - 449, 227, 253, 206, 103, 228, 280, 160, 282, 254, - 190, 110, 304, 281, 112, 309, 448, 305, 447, 310, - 446, 445, 283, 41, 41, 41, 41, 47, 47, 47, - - 47, 53, 53, 53, 53, 57, 57, 57, 57, 59, - 59, 59, 59, 61, 61, 61, 61, 104, 104, 104, - 104, 106, 106, 106, 106, 109, 109, 114, 444, 114, - 114, 115, 115, 115, 115, 443, 442, 441, 440, 439, - 438, 437, 436, 435, 434, 433, 432, 431, 430, 429, - 428, 427, 426, 425, 424, 423, 422, 421, 420, 419, - 418, 417, 416, 415, 414, 413, 412, 411, 410, 409, - 408, 407, 406, 405, 404, 403, 402, 401, 400, 399, - 398, 397, 396, 395, 394, 393, 392, 391, 390, 389, - 388, 387, 386, 385, 384, 383, 382, 381, 380, 379, - - 378, 377, 376, 375, 374, 373, 372, 371, 370, 369, - 368, 367, 366, 365, 364, 363, 309, 362, 361, 360, - 359, 358, 357, 356, 355, 354, 353, 352, 351, 350, - 349, 348, 347, 346, 345, 344, 343, 342, 341, 340, - 339, 338, 337, 336, 335, 334, 333, 332, 331, 330, - 329, 328, 327, 326, 325, 324, 323, 322, 321, 320, - 319, 318, 317, 316, 315, 314, 313, 312, 311, 308, - 307, 306, 303, 302, 301, 300, 299, 298, 297, 296, - 295, 294, 293, 292, 291, 290, 289, 288, 287, 286, - 285, 284, 279, 278, 277, 276, 275, 274, 273, 272, - - 271, 270, 269, 268, 267, 266, 265, 264, 263, 262, - 261, 260, 259, 258, 257, 256, 255, 252, 251, 250, - 249, 248, 247, 246, 245, 244, 243, 242, 241, 240, - 239, 238, 237, 236, 235, 234, 233, 232, 231, 230, - 229, 226, 225, 224, 223, 222, 221, 220, 219, 83, - 218, 217, 216, 215, 214, 213, 212, 211, 210, 209, - 208, 207, 204, 203, 202, 201, 200, 199, 198, 197, - 196, 195, 156, 194, 193, 192, 191, 188, 187, 186, - 185, 184, 183, 182, 181, 180, 179, 178, 177, 176, - 175, 174, 173, 172, 171, 170, 169, 168, 167, 164, - - 163, 162, 161, 116, 107, 105, 158, 157, 156, 155, - 154, 153, 152, 149, 148, 147, 144, 141, 140, 139, - 83, 135, 134, 133, 132, 131, 130, 127, 122, 121, - 120, 119, 118, 117, 66, 116, 108, 107, 105, 100, - 99, 98, 97, 87, 83, 82, 81, 80, 79, 75, - 66, 454, 62, 62, 40, 15, 454, 454, 454, 454, - 454, 454, 454, 454, 454, 454, 454, 454, 454, 454, - 454, 454, 454, 454, 454, 454, 454, 454, 454, 454, - 454, 454, 454, 454, 454, 454, 454, 454, 454, 454, - 454, 454, 454 - + 54, 72, 76, 85, 113, 471, 77, 89, 150, 73, + 86, 90, 92, 95, 470, 93, 78, 87, 58, 151, + 91, 96, 102, 74, 102, 94, 139, 140, 97, 124, + 125, 129, 145, 130, 146, 154, 111, 103, 141, 469, + 126, 131, 104, 127, 148, 102, 149, 102, 111, 114, + 163, 114, 169, 155, 195, 170, 317, 212, 293, 468, + 103, 318, 111, 213, 164, 104, 235, 467, 196, 262, + 236, 291, 294, 322, 113, 466, 263, 323, 292, 41, + + 41, 41, 41, 47, 47, 47, 47, 53, 53, 53, + 53, 57, 57, 57, 57, 59, 59, 59, 59, 61, + 61, 61, 61, 105, 105, 105, 105, 107, 107, 107, + 107, 110, 110, 115, 465, 115, 115, 116, 116, 116, + 116, 464, 463, 462, 461, 460, 459, 458, 457, 456, + 455, 454, 453, 452, 451, 450, 449, 448, 447, 446, + 445, 444, 443, 442, 441, 440, 439, 438, 437, 436, + 435, 434, 433, 432, 431, 430, 429, 428, 427, 426, + 425, 424, 423, 422, 421, 420, 419, 418, 417, 416, + 415, 414, 413, 412, 411, 410, 409, 408, 407, 406, + + 405, 404, 403, 402, 401, 400, 399, 398, 397, 396, + 395, 394, 393, 392, 391, 390, 389, 388, 387, 386, + 385, 384, 383, 382, 381, 380, 379, 378, 322, 377, + 376, 375, 374, 373, 372, 371, 370, 369, 368, 367, + 366, 365, 364, 363, 362, 361, 360, 359, 358, 357, + 356, 355, 354, 353, 352, 351, 350, 349, 348, 347, + 346, 345, 344, 343, 342, 341, 340, 339, 338, 337, + 336, 335, 334, 333, 332, 331, 330, 329, 328, 327, + 326, 325, 324, 321, 320, 319, 316, 315, 314, 313, + 312, 311, 310, 309, 308, 307, 306, 305, 304, 303, + + 302, 301, 300, 299, 298, 297, 296, 295, 290, 289, + 288, 287, 286, 285, 284, 283, 282, 281, 280, 279, + 278, 277, 276, 275, 274, 273, 272, 271, 270, 269, + 268, 267, 266, 265, 264, 261, 260, 259, 258, 257, + 256, 255, 254, 253, 252, 251, 250, 249, 248, 247, + 246, 245, 244, 243, 242, 241, 240, 239, 238, 237, + 234, 233, 232, 231, 230, 229, 228, 227, 226, 84, + 225, 224, 223, 222, 221, 220, 219, 218, 217, 216, + 215, 214, 211, 210, 209, 208, 207, 206, 205, 204, + 203, 202, 160, 201, 200, 199, 198, 197, 194, 193, + + 192, 191, 190, 189, 188, 187, 186, 185, 184, 183, + 182, 181, 180, 179, 178, 177, 176, 175, 174, 173, + 172, 171, 168, 167, 166, 165, 117, 108, 106, 162, + 161, 160, 159, 158, 157, 156, 153, 152, 147, 144, + 143, 142, 84, 138, 137, 136, 135, 134, 133, 132, + 128, 123, 122, 121, 120, 119, 118, 66, 117, 109, + 108, 106, 101, 100, 99, 98, 88, 84, 83, 80, + 79, 75, 66, 476, 62, 62, 40, 15, 476, 476, + 476, 476, 476, 476, 476, 476, 476, 476, 476, 476, + 476, 476, 476, 476, 476, 476, 476, 476, 476, 476, + + 476, 476, 476, 476, 476, 476, 476, 476, 476, 476, + 476, 476, 476, 476, 476 } ; -static yyconst short int yy_chk[594] = +static yyconst short int yy_chk[616] = { 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 3, 3, 17, 3, 17, 4, 4, 4, 3, 4, 5, 6, - 465, 461, 4, 5, 6, 7, 7, 7, 7, 450, + 487, 483, 4, 5, 6, 7, 7, 7, 7, 472, 7, 7, 7, 11, 11, 11, 7, 8, 8, 8, 8, 56, 8, 8, 8, 12, 12, 12, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 19, 22, 19, 33, 76, 449, 56, 33, 22, + 9, 19, 22, 19, 28, 471, 468, 56, 58, 22, - 60, 22, 60, 22, 63, 76, 63, 33, 9, 10, + 60, 22, 60, 22, 63, 467, 63, 28, 9, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, - 10, 23, 25, 31, 35, 40, 25, 40, 34, 23, - 31, 34, 35, 58, 95, 447, 25, 31, 10, 35, - 40, 34, 89, 23, 89, 40, 74, 74, 446, 85, - 85, 91, 95, 91, 101, 110, 101, 74, 112, 58, - 74, 85, 113, 117, 113, 123, 146, 163, 123, 101, - 445, 188, 215, 163, 101, 188, 242, 117, 243, 215, - 146, 110, 270, 242, 112, 274, 442, 270, 440, 274, - 439, 438, 243, 455, 455, 455, 455, 456, 456, 456, - - 456, 457, 457, 457, 457, 458, 458, 458, 458, 459, - 459, 459, 459, 460, 460, 460, 460, 462, 462, 462, - 462, 463, 463, 463, 463, 464, 464, 466, 435, 466, - 466, 467, 467, 467, 467, 434, 433, 431, 430, 429, - 428, 427, 426, 424, 423, 422, 421, 420, 419, 417, - 416, 415, 414, 413, 411, 410, 409, 408, 407, 405, - 404, 403, 402, 401, 400, 398, 397, 396, 395, 394, - 393, 392, 390, 389, 388, 387, 386, 385, 384, 383, - 381, 379, 378, 377, 375, 374, 373, 372, 371, 370, - 368, 366, 365, 364, 363, 362, 361, 360, 359, 358, - - 357, 356, 355, 354, 353, 352, 351, 350, 349, 348, - 347, 346, 345, 344, 341, 340, 338, 337, 336, 335, - 334, 333, 332, 331, 330, 329, 328, 327, 326, 325, - 322, 321, 320, 319, 318, 317, 316, 315, 314, 313, - 312, 310, 308, 307, 306, 305, 304, 303, 302, 300, - 299, 296, 295, 294, 293, 292, 291, 290, 288, 287, - 286, 283, 282, 281, 280, 279, 278, 277, 276, 273, - 272, 271, 268, 267, 266, 264, 263, 262, 260, 258, - 257, 256, 255, 254, 253, 252, 250, 249, 248, 247, - 245, 244, 241, 240, 239, 238, 237, 236, 235, 234, - - 233, 232, 231, 230, 229, 228, 227, 226, 225, 224, - 223, 222, 221, 219, 218, 217, 216, 213, 212, 211, - 210, 209, 208, 207, 206, 205, 204, 203, 202, 201, - 200, 199, 198, 197, 196, 194, 193, 192, 191, 190, - 189, 187, 186, 185, 184, 181, 180, 179, 178, 176, - 175, 174, 173, 172, 171, 170, 169, 168, 167, 166, - 165, 164, 162, 161, 160, 159, 158, 157, 155, 154, - 153, 152, 151, 150, 149, 148, 147, 145, 144, 143, - 142, 141, 140, 139, 138, 137, 136, 135, 134, 133, - 132, 131, 130, 129, 128, 127, 126, 125, 124, 122, - - 121, 120, 118, 115, 106, 104, 103, 102, 100, 99, - 98, 97, 96, 94, 93, 92, 90, 88, 87, 86, - 84, 82, 81, 80, 79, 78, 77, 75, 73, 72, - 71, 70, 69, 68, 66, 65, 49, 45, 44, 39, - 38, 37, 36, 32, 30, 29, 28, 27, 26, 24, - 20, 15, 14, 13, 2, 454, 454, 454, 454, 454, - 454, 454, 454, 454, 454, 454, 454, 454, 454, 454, - 454, 454, 454, 454, 454, 454, 454, 454, 454, 454, - 454, 454, 454, 454, 454, 454, 454, 454, 454, 454, - 454, 454, 454 - + 10, 23, 25, 31, 58, 466, 25, 33, 93, 23, + 31, 33, 34, 35, 463, 34, 25, 31, 10, 93, + 33, 35, 40, 23, 40, 34, 86, 86, 35, 74, + 74, 76, 90, 76, 90, 96, 111, 40, 86, 462, + 74, 76, 40, 74, 92, 102, 92, 102, 113, 114, + 118, 114, 124, 96, 149, 124, 281, 167, 252, 460, + 102, 281, 111, 167, 118, 102, 194, 459, 149, 222, + 194, 251, 252, 285, 113, 458, 222, 285, 251, 477, + + 477, 477, 477, 478, 478, 478, 478, 479, 479, 479, + 479, 480, 480, 480, 480, 481, 481, 481, 481, 482, + 482, 482, 482, 484, 484, 484, 484, 485, 485, 485, + 485, 486, 486, 488, 455, 488, 488, 489, 489, 489, + 489, 454, 453, 451, 450, 449, 448, 447, 446, 445, + 443, 442, 441, 440, 439, 438, 437, 435, 434, 433, + 432, 431, 429, 428, 427, 426, 425, 424, 422, 421, + 420, 419, 418, 417, 415, 414, 413, 412, 411, 410, + 409, 408, 406, 405, 404, 403, 402, 401, 400, 399, + 397, 395, 394, 393, 391, 390, 389, 388, 387, 386, + + 385, 383, 381, 380, 379, 378, 377, 376, 375, 374, + 373, 372, 371, 370, 369, 368, 367, 366, 365, 364, + 363, 362, 361, 360, 359, 358, 355, 354, 352, 351, + 350, 349, 348, 347, 346, 345, 344, 343, 342, 341, + 340, 339, 338, 335, 334, 333, 332, 331, 330, 329, + 328, 327, 326, 325, 323, 321, 320, 319, 318, 317, + 315, 314, 312, 311, 308, 307, 306, 305, 304, 303, + 302, 301, 299, 298, 297, 294, 293, 292, 291, 290, + 289, 288, 287, 284, 283, 282, 279, 278, 277, 276, + 274, 273, 272, 270, 268, 267, 266, 265, 264, 263, + + 262, 261, 259, 258, 257, 256, 254, 253, 250, 249, + 248, 247, 246, 245, 244, 243, 242, 241, 240, 239, + 238, 237, 236, 235, 234, 233, 232, 231, 230, 229, + 227, 226, 225, 224, 223, 220, 219, 218, 217, 216, + 215, 214, 213, 212, 211, 210, 209, 208, 207, 206, + 205, 204, 203, 201, 200, 199, 198, 197, 196, 195, + 193, 192, 191, 190, 187, 186, 185, 184, 182, 181, + 180, 179, 178, 177, 175, 174, 173, 172, 171, 170, + 169, 168, 166, 165, 164, 163, 162, 161, 159, 158, + 157, 156, 155, 154, 153, 152, 151, 150, 148, 147, + + 146, 145, 144, 143, 142, 141, 140, 139, 138, 137, + 136, 135, 134, 133, 132, 131, 130, 129, 128, 127, + 126, 125, 123, 122, 121, 119, 116, 107, 105, 104, + 103, 101, 100, 99, 98, 97, 95, 94, 91, 89, + 88, 87, 85, 83, 82, 81, 80, 79, 78, 77, + 75, 73, 72, 71, 70, 69, 68, 66, 65, 49, + 45, 44, 39, 38, 37, 36, 32, 30, 29, 27, + 26, 24, 20, 15, 14, 13, 2, 476, 476, 476, + 476, 476, 476, 476, 476, 476, 476, 476, 476, 476, + 476, 476, 476, 476, 476, 476, 476, 476, 476, 476, + + 476, 476, 476, 476, 476, 476, 476, 476, 476, 476, + 476, 476, 476, 476, 476 } ; static yy_state_type yy_last_accepting_state; @@ -675,7 +685,7 @@ char *yytext; #define defineredef 5 #define definesym 6 -#line 674 "lexer.c" +#line 684 "lexer.c" /* Macros after this point can all be overridden by user definitions in * section 1. @@ -832,7 +842,7 @@ YY_DECL #line 27 "lexer.l" -#line 831 "lexer.c" +#line 841 "lexer.c" if ( yy_init ) { @@ -884,13 +894,13 @@ yy_match: while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 455 ) + if ( yy_current_state >= 477 ) yy_c = yy_meta[(unsigned int) yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; ++yy_cp; } - while ( yy_base[yy_current_state] != 556 ); + while ( yy_base[yy_current_state] != 578 ); yy_find_action: yy_act = yy_accept[yy_current_state]; @@ -1164,31 +1174,55 @@ case 30: YY_RULE_SETUP #line 187 "lexer.l" { - lmsg ("any"); - return (ANY); + lmsg ("headerinspection"); + return (HEADERINSPECTION); } YY_BREAK case 31: YY_RULE_SETUP #line 192 "lexer.l" { + lmsg ("deep"); + return (DEEP); +} + YY_BREAK +case 32: +YY_RULE_SETUP +#line 197 "lexer.l" +{ + lmsg ("shallow"); + return (SHALLOW); +} + YY_BREAK +case 33: +YY_RULE_SETUP +#line 202 "lexer.l" +{ + lmsg ("any"); + return (ANY); +} + YY_BREAK +case 34: +YY_RULE_SETUP +#line 207 "lexer.l" +{ lmsg ("stickyhttp"); warning ("The 'stickyhttp protocol is obsolte.\n" "You should change to 'http'."); return (HTTP); } YY_BREAK -case 32: +case 35: YY_RULE_SETUP -#line 199 "lexer.l" +#line 214 "lexer.l" { lmsg ("http"); return (HTTP); } YY_BREAK -case 33: +case 36: YY_RULE_SETUP -#line 204 "lexer.l" +#line 219 "lexer.l" { lmsg ("throughputlog"); BEGIN (stringstate); @@ -1197,9 +1231,9 @@ YY_RULE_SETUP return (THROUGHPUTLOG); } YY_BREAK -case 34: +case 37: YY_RULE_SETUP -#line 212 "lexer.l" +#line 227 "lexer.l" { lmsg ("trafficlog"); BEGIN (stringstate); @@ -1208,9 +1242,9 @@ YY_RULE_SETUP return (TRAFFICLOG); } YY_BREAK -case 35: +case 38: YY_RULE_SETUP -#line 220 "lexer.l" +#line 235 "lexer.l" { lmsg ("dumptraffic"); warning ("The 'dumptraffic' statement is obsolete.\n" @@ -1221,9 +1255,9 @@ YY_RULE_SETUP return (TRAFFICLOG); } YY_BREAK -case 36: +case 39: YY_RULE_SETUP -#line 230 "lexer.l" +#line 245 "lexer.l" { lmsg ("onstart"); BEGIN (stringstate); @@ -1232,9 +1266,9 @@ YY_RULE_SETUP return (ONSTART); } YY_BREAK -case 37: +case 40: YY_RULE_SETUP -#line 238 "lexer.l" +#line 253 "lexer.l" { lmsg ("onfail"); BEGIN (stringstate); @@ -1243,9 +1277,9 @@ YY_RULE_SETUP return (ONFAIL); } YY_BREAK -case 38: +case 41: YY_RULE_SETUP -#line 246 "lexer.l" +#line 261 "lexer.l" { lmsg ("onend"); BEGIN (stringstate); @@ -1254,9 +1288,9 @@ YY_RULE_SETUP return (ONEND); } YY_BREAK -case 39: +case 42: YY_RULE_SETUP -#line 254 "lexer.l" +#line 269 "lexer.l" { lmsg ("stickycookie"); BEGIN (stringstate); @@ -1265,9 +1299,9 @@ YY_RULE_SETUP return (STICKYCOOKIE); } YY_BREAK -case 40: +case 43: YY_RULE_SETUP -#line 262 "lexer.l" +#line 277 "lexer.l" { lmsg ("addclientheader"); BEGIN (stringstate); @@ -1276,9 +1310,9 @@ YY_RULE_SETUP return (ADDCLIENTHEADER); } YY_BREAK -case 41: +case 44: YY_RULE_SETUP -#line 270 "lexer.l" +#line 285 "lexer.l" { lmsg ("setclientheader"); BEGIN (stringstate); @@ -1287,9 +1321,9 @@ YY_RULE_SETUP return (SETCLIENTHEADER); } YY_BREAK -case 42: +case 45: YY_RULE_SETUP -#line 278 "lexer.l" +#line 293 "lexer.l" { lmsg ("appendclientheader"); BEGIN (stringstate); @@ -1298,9 +1332,9 @@ YY_RULE_SETUP return (APPENDCLIENTHEADER); } YY_BREAK -case 43: +case 46: YY_RULE_SETUP -#line 286 "lexer.l" +#line 301 "lexer.l" { lmsg ("addserverheader"); BEGIN (stringstate); @@ -1309,9 +1343,9 @@ YY_RULE_SETUP return (ADDSERVERHEADER); } YY_BREAK -case 44: +case 47: YY_RULE_SETUP -#line 294 "lexer.l" +#line 309 "lexer.l" { lmsg ("setserverheader"); BEGIN (stringstate); @@ -1320,9 +1354,9 @@ YY_RULE_SETUP return (SETSERVERHEADER); } YY_BREAK -case 45: +case 48: YY_RULE_SETUP -#line 302 "lexer.l" +#line 317 "lexer.l" { lmsg ("appendserverheader"); BEGIN (stringstate); @@ -1331,9 +1365,9 @@ YY_RULE_SETUP return (APPENDSERVERHEADER); } YY_BREAK -case 46: +case 49: YY_RULE_SETUP -#line 310 "lexer.l" +#line 325 "lexer.l" { lmsg ("allowfrom"); BEGIN (stringstate); @@ -1342,9 +1376,9 @@ YY_RULE_SETUP return (ALLOWFROM); } YY_BREAK -case 47: +case 50: YY_RULE_SETUP -#line 318 "lexer.l" +#line 333 "lexer.l" { lmsg ("denyfrom"); BEGIN (stringstate); @@ -1353,9 +1387,9 @@ YY_RULE_SETUP return (DENYFROM); } YY_BREAK -case 48: +case 51: YY_RULE_SETUP -#line 326 "lexer.l" +#line 341 "lexer.l" { lmsg ("allowfile"); BEGIN (stringstate); @@ -1364,9 +1398,9 @@ YY_RULE_SETUP return (ALLOWFILE); } YY_BREAK -case 49: +case 52: YY_RULE_SETUP -#line 334 "lexer.l" +#line 349 "lexer.l" { lmsg ("denyfile"); BEGIN (stringstate); @@ -1375,110 +1409,110 @@ YY_RULE_SETUP return (DENYFILE); } YY_BREAK -case 50: +case 53: YY_RULE_SETUP -#line 342 "lexer.l" +#line 357 "lexer.l" { lmsg ("on"); return (ON); } YY_BREAK -case 51: +case 54: YY_RULE_SETUP -#line 347 "lexer.l" +#line 362 "lexer.l" { lmsg ("off"); return (OFF); } YY_BREAK -case 52: +case 55: YY_RULE_SETUP -#line 352 "lexer.l" +#line 367 "lexer.l" { llmsg ("identifier", yytext); return (IDENTIFIER); } YY_BREAK -case 53: +case 56: YY_RULE_SETUP -#line 357 "lexer.l" +#line 372 "lexer.l" { llmsg ("number", yytext); return (NUMBER); } YY_BREAK -case 54: +case 57: YY_RULE_SETUP -#line 362 "lexer.l" +#line 377 "lexer.l" { lmsg ("space(s)"); } YY_BREAK -case 55: +case 58: YY_RULE_SETUP -#line 366 "lexer.l" +#line 381 "lexer.l" { lmsg ("newline"); yylineno++; } YY_BREAK -case 56: +case 59: YY_RULE_SETUP -#line 371 "lexer.l" +#line 386 "lexer.l" { llmsg ("lone char", yytext); return (*yytext); } YY_BREAK -case 57: +case 60: YY_RULE_SETUP -#line 376 "lexer.l" +#line 391 "lexer.l" { lmsg ("C-comment starts"); BEGIN(commentstate); } YY_BREAK -case 58: +case 61: YY_RULE_SETUP -#line 380 "lexer.l" +#line 395 "lexer.l" { lmsg ("C-comment ends"); BEGIN(0); } YY_BREAK -case 59: +case 62: YY_RULE_SETUP -#line 384 "lexer.l" +#line 399 "lexer.l" { yylineno++; } YY_BREAK -case 60: +case 63: YY_RULE_SETUP -#line 387 "lexer.l" +#line 402 "lexer.l" ; YY_BREAK -case 61: +case 64: YY_RULE_SETUP -#line 389 "lexer.l" +#line 404 "lexer.l" { llmsg ("string part", yytext); laststring = xstrcat (laststring, yytext + 1); laststring[strlen(laststring) - 1] = 0; } YY_BREAK -case 62: +case 65: YY_RULE_SETUP -#line 394 "lexer.l" +#line 409 "lexer.l" { llmsg ("string part", yytext); laststring = xstrcat (laststring, yytext + 1); laststring[strlen(laststring) - 1] = 0; } YY_BREAK -case 63: +case 66: YY_RULE_SETUP -#line 399 "lexer.l" +#line 414 "lexer.l" { BEGIN (0); unput (';'); @@ -1486,9 +1520,9 @@ YY_RULE_SETUP return (STRING); } YY_BREAK -case 64: +case 67: YY_RULE_SETUP -#line 405 "lexer.l" +#line 420 "lexer.l" { if (laststring) { laststring = xstrcat (laststring, yytext); @@ -1496,17 +1530,17 @@ YY_RULE_SETUP } } YY_BREAK -case 65: +case 68: YY_RULE_SETUP -#line 411 "lexer.l" +#line 426 "lexer.l" { llmsg ("string part", yytext); laststring = xstrcat (laststring, yytext); } YY_BREAK -case 66: +case 69: YY_RULE_SETUP -#line 415 "lexer.l" +#line 430 "lexer.l" { if (laststring) { laststring = xstrcat (laststring, " "); @@ -1515,9 +1549,9 @@ YY_RULE_SETUP yylineno++; } YY_BREAK -case 67: +case 70: YY_RULE_SETUP -#line 423 "lexer.l" +#line 438 "lexer.l" { lmsg ("includefile"); /* parser_skipline(); */ @@ -1526,38 +1560,38 @@ YY_RULE_SETUP } YY_BREAK case YY_STATE_EOF(includestate): -#line 429 "lexer.l" +#line 444 "lexer.l" { error ("Unterminated #include"); } YY_BREAK -case 68: +case 71: YY_RULE_SETUP -#line 432 "lexer.l" +#line 447 "lexer.l" ; YY_BREAK -case 69: +case 72: YY_RULE_SETUP -#line 433 "lexer.l" +#line 448 "lexer.l" { yylineno++; } YY_BREAK -case 70: +case 73: YY_RULE_SETUP -#line 436 "lexer.l" +#line 451 "lexer.l" { error ("Illegal character 0x%2.2x in #include line", *yytext); } YY_BREAK -case 71: +case 74: YY_RULE_SETUP -#line 440 "lexer.l" +#line 455 "lexer.l" ; YY_BREAK -case 72: +case 75: YY_RULE_SETUP -#line 441 "lexer.l" +#line 456 "lexer.l" { symtab_start (yytext); BEGIN (defineredef); @@ -1566,54 +1600,54 @@ YY_RULE_SETUP case YY_STATE_EOF(definestate): case YY_STATE_EOF(defineredef): case YY_STATE_EOF(definesym): -#line 445 "lexer.l" +#line 460 "lexer.l" { error ("Unterminated #define"); } YY_BREAK -case 73: +case 76: YY_RULE_SETUP -#line 448 "lexer.l" +#line 463 "lexer.l" { error ("Unterminated #define"); } YY_BREAK -case 74: +case 77: YY_RULE_SETUP -#line 451 "lexer.l" +#line 466 "lexer.l" { error ("Unrecognized character '%c' in #define", *yytext); } YY_BREAK -case 75: +case 78: YY_RULE_SETUP -#line 455 "lexer.l" +#line 470 "lexer.l" { BEGIN (definesym); } YY_BREAK -case 76: +case 79: YY_RULE_SETUP -#line 458 "lexer.l" +#line 473 "lexer.l" { symtab_set (yytext); } YY_BREAK -case 77: +case 80: YY_RULE_SETUP -#line 461 "lexer.l" +#line 476 "lexer.l" { yylineno++; symtab_end(); BEGIN (0); } YY_BREAK -case 78: +case 81: YY_RULE_SETUP -#line 466 "lexer.l" +#line 481 "lexer.l" ECHO; YY_BREAK -#line 1612 "lexer.c" +#line 1646 "lexer.c" case YY_STATE_EOF(INITIAL): case YY_STATE_EOF(stringstate): case YY_STATE_EOF(commentstate): @@ -1908,7 +1942,7 @@ static yy_state_type yy_get_previous_state() while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 455 ) + if ( yy_current_state >= 477 ) yy_c = yy_meta[(unsigned int) yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; @@ -1943,11 +1977,11 @@ yy_state_type yy_current_state; while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 455 ) + if ( yy_current_state >= 477 ) yy_c = yy_meta[(unsigned int) yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; - yy_is_jam = (yy_current_state == 454); + yy_is_jam = (yy_current_state == 476); return yy_is_jam ? 0 : yy_current_state; } @@ -2503,4 +2537,4 @@ int main() return 0; } #endif -#line 466 "lexer.l" +#line 481 "lexer.l" diff --git a/src/lib/lexer.l b/src/lib/lexer.l @@ -184,6 +184,21 @@ type { return (TYPE); } +headerinspection { + lmsg ("headerinspection"); + return (HEADERINSPECTION); +} + +deep { + lmsg ("deep"); + return (DEEP); +} + +shallow { + lmsg ("shallow"); + return (SHALLOW); +} + any { lmsg ("any"); return (ANY); diff --git a/src/lib/lockreporter.c b/src/lib/lockreporter.c @@ -1,5 +1,5 @@ /************************************************************************* - * This file is part of Crosroads 1.44, a load balancer and fail over + * This file is part of Crosroads 1.45, 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.44, a load balancer and fail over + * This file is part of Crosroads 1.45, 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.44, a load balancer and fail over + * This file is part of Crosroads 1.45, 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.44, a load balancer and fail over + * This file is part of Crosroads 1.45, 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.44, a load balancer and fail over + * This file is part of Crosroads 1.45, 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.44, a load balancer and fail over + * This file is part of Crosroads 1.45, 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.44, a load balancer and fail over + * This file is part of Crosroads 1.45, 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.44, a load balancer and fail over + * This file is part of Crosroads 1.45, 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.44, a load balancer and fail over + * This file is part of Crosroads 1.45, 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.44, a load balancer and fail over + * This file is part of Crosroads 1.45, 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.44, a load balancer and fail over + * This file is part of Crosroads 1.45, a load balancer and fail over * utility for TCP. Copyright (c) Karel Kubat, distributed under GPL. * Visit http://crossroads.e-tunity.com for information. *************************************************************************/ @@ -13,8 +13,8 @@ unsigned char *net_bufread (int sock, int max, int *nread, /* Make sure we have the buffers. */ if (!clbuf) { - clbuf = xmalloc (TCP_BUFSZ); - srbuf = xmalloc (TCP_BUFSZ); + clbuf = xmalloc (tcp_bufsz); + srbuf = xmalloc (tcp_bufsz); clbufmax = srbufmax = clbufpos = srbufpos = 0; msg ("Service %s: Allocated client and server buffers", activeservice->name); @@ -32,7 +32,7 @@ unsigned char *net_bufread (int sock, int max, int *nread, /* If buffer is empty, do an actual read */ if (! *bufmax) { - *bufmax = net_read (sock, TCP_BUFSZ, buf, is_client); + *bufmax = net_read (sock, tcp_bufsz, buf, is_client); msg ("Service %s: Got %d bytes from %s", activeservice->name, *bufmax, is_client ? "client" : "server"); *bufpos = 0; diff --git a/src/lib/netcopy.c b/src/lib/netcopy.c @@ -1,5 +1,5 @@ /************************************************************************* - * This file is part of Crosroads 1.44, a load balancer and fail over + * This file is part of Crosroads 1.45, 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.44, a load balancer and fail over + * This file is part of Crosroads 1.45, 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.44, a load balancer and fail over + * This file is part of Crosroads 1.45, 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.44, a load balancer and fail over + * This file is part of Crosroads 1.45, a load balancer and fail over * utility for TCP. Copyright (c) Karel Kubat, distributed under GPL. * Visit http://crossroads.e-tunity.com for information. *************************************************************************/ @@ -57,6 +57,9 @@ # define USERACCOUNT 303 # define BYCLIENTIP 304 # define RETRIES 305 +# define HEADERINSPECTION 306 +# define DEEP 307 +# define SHALLOW 308 #line 3 "parser.y" @@ -195,12 +198,12 @@ static void setuseraccount (char *username) { -#define YYFINAL 202 +#define YYFINAL 210 #define YYFLAG -32768 -#define YYNTBASE 55 +#define YYNTBASE 58 /* YYTRANSLATE(YYLEX) -- Bison token number corresponding to YYLEX. */ -#define YYTRANSLATE(x) ((unsigned)(x) <= 305 ? yytranslate[x] : 135) +#define YYTRANSLATE(x) ((unsigned)(x) <= 308 ? yytranslate[x] : 142) /* YYTRANSLATE[YYLEX] -- Bison token number corresponding to YYLEX. */ static const char yytranslate[] = @@ -210,14 +213,14 @@ static const char yytranslate[] = 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 54, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 57, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 52, 2, 53, 2, 2, 2, 2, + 2, 2, 2, 55, 2, 56, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, @@ -235,7 +238,7 @@ static const char yytranslate[] = 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, - 46, 47, 48, 49, 50, 51 + 46, 47, 48, 49, 50, 51, 52, 53, 54 }; #if YYDEBUG @@ -243,53 +246,56 @@ static const short yyprhs[] = { 0, 0, 3, 5, 11, 14, 17, 20, 22, 25, 27, 29, 31, 33, 35, 37, 39, 41, 43, 45, - 47, 49, 51, 53, 55, 57, 61, 65, 68, 71, - 74, 79, 81, 83, 88, 90, 92, 93, 96, 99, - 101, 104, 106, 108, 110, 112, 114, 116, 118, 120, - 124, 127, 131, 135, 139, 143, 147, 151, 154, 156, - 158, 162, 166, 170, 174, 177, 183, 186, 189, 191, - 194, 196, 198, 200, 202, 204, 206, 208, 210, 212, - 214, 216, 218, 220, 222, 224, 226, 228, 230, 232, - 237, 241, 245, 247, 251, 255, 259, 263, 267, 271, - 274, 277, 281, 284, 288, 292, 296, 300, 304, 308, - 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, - 321, 322, 323, 324, 325, 326, 327, 328 + 47, 49, 51, 53, 55, 57, 59, 63, 67, 70, + 73, 76, 81, 83, 85, 90, 92, 94, 95, 98, + 101, 103, 106, 108, 110, 112, 114, 116, 118, 120, + 122, 126, 129, 133, 137, 141, 145, 149, 153, 156, + 158, 160, 164, 167, 169, 171, 175, 179, 183, 187, + 190, 196, 199, 202, 204, 207, 209, 211, 213, 215, + 217, 219, 221, 223, 225, 227, 229, 231, 233, 235, + 237, 239, 241, 243, 245, 250, 254, 258, 260, 264, + 268, 272, 276, 280, 284, 287, 290, 294, 297, 301, + 305, 309, 313, 317, 321, 324, 325, 326, 327, 328, + 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, + 339, 340, 341, 342 }; static const short yyrhs[] = { - 55, 56, 0, 56, 0, 57, 58, 52, 59, 53, - 0, 121, 3, 0, 129, 4, 0, 59, 60, 0, - 60, 0, 123, 61, 0, 62, 0, 63, 0, 67, - 0, 69, 0, 78, 0, 79, 0, 80, 0, 81, - 0, 82, 0, 83, 0, 86, 0, 88, 0, 87, - 0, 89, 0, 76, 0, 91, 0, 5, 65, 66, - 0, 31, 64, 66, 0, 131, 19, 0, 119, 6, - 0, 124, 54, 0, 8, 125, 68, 66, 0, 10, - 0, 11, 0, 12, 74, 70, 66, 0, 71, 0, - 73, 0, 0, 29, 72, 0, 119, 6, 0, 106, - 0, 126, 75, 0, 13, 0, 21, 0, 22, 0, - 23, 0, 27, 0, 24, 0, 47, 0, 50, 0, - 49, 77, 66, 0, 134, 19, 0, 14, 65, 66, - 0, 20, 65, 66, 0, 15, 65, 66, 0, 25, - 65, 66, 0, 26, 65, 66, 0, 33, 84, 66, - 0, 132, 85, 0, 34, 0, 35, 0, 43, 90, - 66, 0, 44, 90, 66, 0, 45, 107, 66, 0, - 46, 107, 66, 0, 133, 19, 0, 7, 92, 52, - 93, 53, 0, 130, 4, 0, 93, 94, 0, 94, - 0, 122, 95, 0, 96, 0, 62, 0, 67, 0, - 101, 0, 103, 0, 102, 0, 104, 0, 105, 0, - 97, 0, 98, 0, 82, 0, 108, 0, 110, 0, - 111, 0, 112, 0, 113, 0, 114, 0, 115, 0, - 100, 0, 9, 120, 99, 66, 0, 16, 65, 66, - 0, 30, 65, 66, 0, 19, 0, 51, 65, 66, - 0, 17, 106, 66, 0, 18, 106, 66, 0, 48, - 106, 66, 0, 28, 107, 66, 0, 32, 107, 66, - 0, 127, 19, 0, 128, 19, 0, 36, 109, 66, - 0, 118, 19, 0, 37, 116, 66, 0, 38, 116, - 66, 0, 39, 116, 66, 0, 40, 116, 66, 0, - 41, 116, 66, 0, 42, 116, 66, 0, 117, 19, + 58, 59, 0, 59, 0, 60, 61, 55, 62, 56, + 0, 127, 3, 0, 135, 4, 0, 62, 63, 0, + 63, 0, 129, 64, 0, 65, 0, 66, 0, 70, + 0, 72, 0, 81, 0, 82, 0, 83, 0, 84, + 0, 85, 0, 86, 0, 89, 0, 92, 0, 94, + 0, 93, 0, 95, 0, 79, 0, 97, 0, 5, + 68, 69, 0, 31, 67, 69, 0, 137, 19, 0, + 125, 6, 0, 130, 57, 0, 8, 131, 71, 69, + 0, 10, 0, 11, 0, 12, 77, 73, 69, 0, + 74, 0, 76, 0, 0, 29, 75, 0, 125, 6, + 0, 112, 0, 132, 78, 0, 13, 0, 21, 0, + 22, 0, 23, 0, 27, 0, 24, 0, 47, 0, + 50, 0, 49, 80, 69, 0, 141, 19, 0, 14, + 68, 69, 0, 20, 68, 69, 0, 15, 68, 69, + 0, 25, 68, 69, 0, 26, 68, 69, 0, 33, + 87, 69, 0, 138, 88, 0, 34, 0, 35, 0, + 52, 90, 69, 0, 139, 91, 0, 53, 0, 54, + 0, 43, 96, 69, 0, 44, 96, 69, 0, 45, + 113, 69, 0, 46, 113, 69, 0, 140, 19, 0, + 7, 98, 55, 99, 56, 0, 136, 4, 0, 99, + 100, 0, 100, 0, 128, 101, 0, 102, 0, 65, + 0, 70, 0, 107, 0, 109, 0, 108, 0, 110, + 0, 111, 0, 103, 0, 104, 0, 85, 0, 114, + 0, 116, 0, 117, 0, 118, 0, 119, 0, 120, + 0, 121, 0, 106, 0, 9, 126, 105, 69, 0, + 16, 68, 69, 0, 30, 68, 69, 0, 19, 0, + 51, 68, 69, 0, 17, 112, 69, 0, 18, 112, + 69, 0, 48, 112, 69, 0, 28, 113, 69, 0, + 32, 113, 69, 0, 133, 19, 0, 134, 19, 0, + 36, 115, 69, 0, 124, 19, 0, 37, 122, 69, + 0, 38, 122, 69, 0, 39, 122, 69, 0, 40, + 122, 69, 0, 41, 122, 69, 0, 42, 122, 69, + 0, 123, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0 + 0, 0, 0 }; #endif @@ -300,17 +306,18 @@ static const short yyrline[] = { 0, 145, 148, 152, 183, 188, 199, 202, 206, 211, 220, 226, 232, 242, 248, 254, 260, 266, 272, 278, - 284, 290, 296, 302, 309, 480, 492, 504, 513, 520, - 525, 538, 542, 548, 557, 559, 561, 565, 582, 589, - 599, 608, 612, 616, 620, 624, 628, 632, 636, 642, - 654, 663, 675, 687, 699, 711, 723, 735, 740, 744, - 750, 762, 774, 786, 798, 807, 817, 829, 837, 843, - 850, 855, 860, 865, 870, 875, 880, 885, 890, 895, - 900, 905, 910, 915, 920, 925, 930, 935, 940, 947, - 960, 972, 984, 990, 1002, 1014, 1026, 1038, 1050, 1062, - 1071, 1080, 1092, 1101, 1113, 1125, 1137, 1149, 1161, 1173, - 1182, 1187, 1192, 1197, 1202, 1207, 1212, 1217, 1222, 1227, - 1232, 1237, 1242, 1247, 1252, 1257, 1262, 1267 + 284, 290, 296, 302, 308, 315, 486, 498, 510, 519, + 526, 531, 544, 548, 554, 563, 565, 567, 571, 588, + 595, 605, 614, 618, 622, 626, 630, 634, 638, 642, + 648, 660, 669, 681, 693, 705, 717, 729, 741, 746, + 750, 756, 768, 773, 777, 783, 795, 807, 819, 831, + 840, 850, 862, 870, 876, 883, 888, 893, 898, 903, + 908, 913, 918, 923, 928, 933, 938, 943, 948, 953, + 958, 963, 968, 973, 980, 993, 1005, 1017, 1023, 1035, + 1047, 1059, 1071, 1083, 1095, 1104, 1113, 1125, 1134, 1146, + 1158, 1170, 1182, 1194, 1206, 1215, 1220, 1225, 1230, 1235, + 1240, 1245, 1250, 1255, 1260, 1265, 1270, 1275, 1280, 1285, + 1290, 1295, 1300, 1305 }; #endif @@ -330,14 +337,16 @@ static const char *const yytname[] = "APPENDCLIENTHEADER", "ADDSERVERHEADER", "SETSERVERHEADER", "APPENDSERVERHEADER", "ALLOWFROM", "DENYFROM", "ALLOWFILE", "DENYFILE", "EXTERNALHANDLER", "ONEND", "USERACCOUNT", "BYCLIENTIP", "RETRIES", - "'{'", "'}'", "';'", "input", "element", "service", "servicename", - "servicestatements", "servicestatement", "servicebody", "portstatement", - "bindstatement", "ipaddress", "number", "semicol", "verbositystatement", - "onoff", "dispatchmodestatement", "dispatchtail", "dispatchover", - "overnumber", "dispatchext", "dispatchmethod", "dispatchmethodspec", + "HEADERINSPECTION", "DEEP", "SHALLOW", "'{'", "'}'", "';'", "input", + "element", "service", "servicename", "servicestatements", + "servicestatement", "servicebody", "portstatement", "bindstatement", + "ipaddress", "number", "semicol", "verbositystatement", "onoff", + "dispatchmodestatement", "dispatchtail", "dispatchover", "overnumber", + "dispatchext", "dispatchmethod", "dispatchmethodspec", "useraccountstatement", "useraccount", "revivingintervalstatement", "backlogstatement", "shmkeystatement", "connectiontimeoutstatement", "maxconnectionsstatement", "typestatement", "typespec", "typespecifier", + "inspectionstatement", "shallowdeepspec", "shallowdeepspecifier", "allowfromstatement", "denyfromstatement", "allowfilestatement", "denyfilestatement", "ipfilters", "backendblock", "backendname", "backenddefinitions", "backenddefinition", "backendstatement", @@ -353,27 +362,28 @@ static const char *const yytname[] = "backendstatement_expected", "servicebody_expected", "semicol_expected", "onoff_expected", "dispatchmethod_expected", "commandline_expected", "filename_expected", "servicename_expected", "backendname_expected", - "ipaddress_expected", "type_expected", "ipfilters_expected", - "useraccount_expected", 0 + "ipaddress_expected", "type_expected", "shallowdeep_expected", + "ipfilters_expected", "useraccount_expected", 0 }; #endif /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ static const short yyr1[] = { - 0, 55, 55, 56, 57, 58, 59, 59, 60, 61, - 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, - 61, 61, 61, 61, 61, 62, 63, 64, 65, 66, - 67, 68, 68, 69, 70, 70, 70, 71, 72, 73, - 74, 75, 75, 75, 75, 75, 75, 75, 75, 76, - 77, 78, 79, 80, 81, 82, 83, 84, 85, 85, - 86, 87, 88, 89, 90, 91, 92, 93, 93, 94, - 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, - 95, 95, 95, 95, 95, 95, 95, 95, 95, 96, - 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, - 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, - 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, - 127, 128, 129, 130, 131, 132, 133, 134 + 0, 58, 58, 59, 60, 61, 62, 62, 63, 64, + 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 65, 66, 67, 68, + 69, 70, 71, 71, 72, 73, 73, 73, 74, 75, + 76, 77, 78, 78, 78, 78, 78, 78, 78, 78, + 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, + 88, 89, 90, 91, 91, 92, 93, 94, 95, 96, + 97, 98, 99, 99, 100, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 102, 103, 104, 105, 106, 107, + 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, + 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, + 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, + 138, 139, 140, 141 }; /* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */ @@ -381,17 +391,18 @@ static const short yyr2[] = { 0, 2, 1, 5, 2, 2, 2, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 3, 3, 2, 2, 2, - 4, 1, 1, 4, 1, 1, 0, 2, 2, 1, - 2, 1, 1, 1, 1, 1, 1, 1, 1, 3, - 2, 3, 3, 3, 3, 3, 3, 2, 1, 1, - 3, 3, 3, 3, 2, 5, 2, 2, 1, 2, + 1, 1, 1, 1, 1, 1, 3, 3, 2, 2, + 2, 4, 1, 1, 4, 1, 1, 0, 2, 2, + 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, + 3, 2, 3, 3, 3, 3, 3, 3, 2, 1, + 1, 3, 2, 1, 1, 3, 3, 3, 3, 2, + 5, 2, 2, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 4, - 3, 3, 1, 3, 3, 3, 3, 3, 3, 2, - 2, 3, 2, 3, 3, 3, 3, 3, 3, 2, + 1, 1, 1, 1, 4, 3, 3, 1, 3, 3, + 3, 3, 3, 3, 2, 2, 3, 2, 3, 3, + 3, 3, 3, 3, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0 + 0, 0, 0, 0 }; /* YYDEFACT[S] -- default rule to reduce with in state S when YYTABLE @@ -399,122 +410,128 @@ static const short yyr2[] = error. */ static const short yydefact[] = { - 114, 114, 2, 122, 0, 1, 0, 0, 4, 116, - 5, 116, 7, 0, 3, 6, 112, 123, 118, 119, - 112, 112, 112, 112, 112, 124, 125, 126, 126, 121, - 121, 127, 8, 9, 10, 11, 12, 23, 13, 14, - 15, 16, 17, 18, 19, 21, 20, 22, 24, 117, - 0, 0, 0, 0, 36, 0, 117, 117, 117, 117, - 117, 117, 0, 117, 0, 117, 0, 117, 117, 0, - 117, 117, 0, 25, 0, 28, 115, 66, 31, 32, - 117, 112, 117, 34, 35, 39, 0, 41, 42, 43, - 44, 46, 45, 47, 48, 40, 51, 53, 52, 54, - 55, 26, 27, 56, 58, 59, 57, 60, 64, 61, - 62, 100, 63, 49, 50, 29, 115, 68, 0, 30, - 37, 0, 33, 99, 65, 67, 113, 112, 120, 120, - 121, 112, 121, 111, 110, 110, 110, 110, 110, 110, - 120, 112, 71, 72, 80, 69, 70, 78, 79, 88, - 73, 75, 74, 76, 77, 81, 82, 83, 84, 85, - 86, 87, 38, 0, 117, 117, 117, 117, 117, 117, - 117, 0, 117, 0, 117, 117, 117, 117, 117, 117, - 117, 92, 117, 90, 94, 95, 97, 91, 98, 101, - 102, 103, 109, 104, 105, 106, 107, 108, 96, 93, - 89, 0, 0 + 119, 119, 2, 127, 0, 1, 0, 0, 4, 121, + 5, 121, 7, 0, 3, 6, 117, 128, 123, 124, + 117, 117, 117, 117, 117, 129, 130, 132, 132, 126, + 126, 133, 131, 8, 9, 10, 11, 12, 24, 13, + 14, 15, 16, 17, 18, 19, 20, 22, 21, 23, + 25, 122, 0, 0, 0, 0, 37, 0, 122, 122, + 122, 122, 122, 122, 0, 122, 0, 122, 0, 122, + 122, 0, 122, 122, 0, 122, 0, 26, 0, 29, + 120, 71, 32, 33, 122, 117, 122, 35, 36, 40, + 0, 42, 43, 44, 45, 47, 46, 48, 49, 41, + 52, 54, 53, 55, 56, 27, 28, 57, 59, 60, + 58, 65, 69, 66, 67, 105, 68, 50, 51, 61, + 63, 64, 62, 30, 120, 73, 0, 31, 38, 0, + 34, 104, 70, 72, 118, 117, 125, 125, 126, 117, + 126, 116, 115, 115, 115, 115, 115, 115, 125, 117, + 76, 77, 85, 74, 75, 83, 84, 93, 78, 80, + 79, 81, 82, 86, 87, 88, 89, 90, 91, 92, + 39, 0, 122, 122, 122, 122, 122, 122, 122, 0, + 122, 0, 122, 122, 122, 122, 122, 122, 122, 97, + 122, 95, 99, 100, 102, 96, 103, 106, 107, 108, + 114, 109, 110, 111, 112, 113, 101, 98, 94, 0, + 0 }; static const short yydefgoto[] = { - 1, 2, 3, 6, 11, 12, 32, 33, 34, 61, - 49, 73, 35, 80, 36, 82, 83, 120, 84, 54, - 95, 37, 71, 38, 39, 40, 41, 42, 43, 63, - 106, 44, 45, 46, 47, 65, 48, 51, 116, 117, - 145, 146, 147, 148, 182, 149, 150, 151, 152, 153, - 154, 85, 68, 155, 170, 156, 157, 158, 159, 160, - 161, 172, 173, 171, 50, 163, 4, 118, 13, 74, - 53, 55, 86, 69, 7, 52, 62, 64, 66, 72 + 1, 2, 3, 6, 11, 12, 33, 34, 35, 63, + 51, 77, 36, 84, 37, 86, 87, 128, 88, 56, + 99, 38, 73, 39, 40, 41, 42, 43, 44, 65, + 110, 45, 75, 122, 46, 47, 48, 49, 67, 50, + 53, 124, 125, 153, 154, 155, 156, 190, 157, 158, + 159, 160, 161, 162, 89, 70, 163, 178, 164, 165, + 166, 167, 168, 169, 180, 181, 179, 52, 171, 4, + 126, 13, 78, 55, 57, 90, 71, 7, 54, 64, + 66, 76, 68, 74 }; static const short yypact[] = { - -32768, 8,-32768,-32768, 7,-32768, -39, 13,-32768,-32768, - -32768, -30,-32768, 58,-32768,-32768,-32768,-32768,-32768,-32768, + -32768, 8,-32768,-32768, 7,-32768, -30, 29,-32768,-32768, + -32768, -16,-32768, 22,-32768,-32768,-32768,-32768,-32768,-32768, -32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768, -32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768, -32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768, - 21, -17, 37, 23, -13, 114,-32768,-32768,-32768,-32768, - -32768,-32768, 25,-32768, 5,-32768, 26,-32768,-32768, 28, - -32768,-32768, 30,-32768, -12,-32768,-32768,-32768,-32768,-32768, - -32768,-32768,-32768,-32768,-32768,-32768, 32,-32768,-32768,-32768, + -32768,-32768, 35, -9, 41, 21, -13, 36,-32768,-32768, + -32768,-32768,-32768,-32768, 31,-32768, 4,-32768, 32,-32768, + -32768, 33,-32768,-32768, 37,-32768, -10,-32768, -3,-32768, -32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768, + 42,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768, -32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768, - -32768,-32768,-32768,-32768,-32768,-32768, 1,-32768, 20,-32768, - -32768, 47,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768, -32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768, + -32768,-32768,-32768,-32768, 6,-32768, 126,-32768,-32768, 58, -32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768, -32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768, - -32768,-32768,-32768, 36,-32768,-32768,-32768,-32768,-32768,-32768, - -32768, 45,-32768, 48,-32768,-32768,-32768,-32768,-32768,-32768, -32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768, -32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768, - -32768, 69,-32768 + -32768, 50,-32768,-32768,-32768,-32768,-32768,-32768,-32768, 51, + -32768, 53,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768, + -32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768, + -32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768, 73, + -32768 }; static const short yypgoto[] = { - -32768, 73,-32768,-32768,-32768, 64,-32768, -42,-32768,-32768, - -2, -56, -41,-32768,-32768,-32768,-32768,-32768,-32768,-32768, - -32768,-32768,-32768,-32768,-32768,-32768,-32768, -38,-32768,-32768, - -32768,-32768,-32768,-32768,-32768, 51,-32768,-32768,-32768, -35, + -32768, 79,-32768,-32768,-32768, 70,-32768, -44,-32768,-32768, + -2, -58, -42,-32768,-32768,-32768,-32768,-32768,-32768,-32768, + -32768,-32768,-32768,-32768,-32768,-32768,-32768, -41,-32768,-32768, + -32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768, 59,-32768, + -32768,-32768, -36,-32768,-32768,-32768,-32768,-32768,-32768,-32768, + -32768,-32768,-32768,-32768, -113, -17,-32768,-32768,-32768,-32768, + -32768,-32768,-32768,-32768, -68,-32768,-32768, 5,-32768,-32768, -32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768, - -32768, -97, 0,-32768,-32768,-32768,-32768,-32768,-32768,-32768, - -32768, -43,-32768,-32768, 4,-32768,-32768,-32768,-32768,-32768, - -32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768 + -32768,-32768,-32768,-32768 }; -#define YYLAST 164 +#define YYLAST 177 static const short yytable[] = { - 96, 97, 98, 99, 100, 101, -120, 103, 201, 107, - 8, 109, 110, 9, 112, 113, 81, 10, 56, 57, - 58, 59, 60, 14, 119, 16, 122, 75, 18, 126, - 70, 165, 166, 78, 79, 76, 127, 128, 129, 104, - 105, 77, 115, 179, 102, 108, 24, 111, 130, 114, - 131, 123, 132, 162, 124, 181, 133, 134, 135, 136, - 137, 138, 139, 16, 190, 17, 18, 192, 140, 202, - 19, 141, 20, 21, 5, 15, 142, 143, 22, 67, - 144, 125, 0, 23, 24, 121, 0, 0, 0, 25, - 0, 26, 174, 175, 176, 177, 178, 0, 0, 0, - 0, 27, 28, 29, 30, 0, 0, 31, 183, 184, - 185, 186, 187, 188, 189, 0, 191, 0, 193, 194, - 195, 196, 197, 198, 199, 164, 200, 87, 0, 168, - 167, 0, 169, 0, 0, 88, 89, 90, 91, 180, - 0, 92, 0, 0, 0, 0, 0, 0, 0, 0, + 100, 101, 102, 103, 104, 105, -125, 107, 209, 111, + 8, 113, 114, 72, 116, 117, 85, 119, 58, 59, + 60, 61, 62, 173, 174, 9, 127, 16, 130, 17, + 18, 82, 83, 10, 19, 187, 20, 21, 108, 109, + 14, 79, 22, 120, 121, 81, 80, 23, 24, 91, + 106, 112, 115, 25, 123, 26, 118, 92, 93, 94, + 95, 131, 132, 96, 170, 27, 28, 29, 30, 189, + 198, 31, 200, 210, 32, 182, 183, 184, 185, 186, + 5, 15, 150, 97, 151, 152, 98, 69, 133, 0, + 129, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 93, 0, 0, 94 + 0, 0, 0, 0, 191, 192, 193, 194, 195, 196, + 197, 175, 199, 177, 201, 202, 203, 204, 205, 206, + 207, 16, 208, 172, 18, 134, 0, 176, 0, 0, + 0, 0, 135, 136, 137, 0, 0, 188, 0, 0, + 0, 0, 24, 0, 138, 0, 139, 0, 140, 0, + 0, 0, 141, 142, 143, 144, 145, 146, 147, 0, + 0, 0, 0, 0, 148, 0, 0, 149 }; static const short yycheck[] = { - 56, 57, 58, 59, 60, 61, 19, 63, 0, 65, - 3, 67, 68, 52, 70, 71, 29, 4, 20, 21, - 22, 23, 24, 53, 80, 5, 82, 6, 8, 9, - 30, 128, 129, 10, 11, 52, 16, 17, 18, 34, - 35, 4, 54, 140, 19, 19, 26, 19, 28, 19, - 30, 19, 32, 6, 53, 19, 36, 37, 38, 39, - 40, 41, 42, 5, 19, 7, 8, 19, 48, 0, - 12, 51, 14, 15, 1, 11, 118, 118, 20, 28, - 118, 116, -1, 25, 26, 81, -1, -1, -1, 31, - -1, 33, 135, 136, 137, 138, 139, -1, -1, -1, - -1, 43, 44, 45, 46, -1, -1, 49, 164, 165, - 166, 167, 168, 169, 170, -1, 172, -1, 174, 175, - 176, 177, 178, 179, 180, 127, 182, 13, -1, 131, - 130, -1, 132, -1, -1, 21, 22, 23, 24, 141, - -1, 27, -1, -1, -1, -1, -1, -1, -1, -1, + 58, 59, 60, 61, 62, 63, 19, 65, 0, 67, + 3, 69, 70, 30, 72, 73, 29, 75, 20, 21, + 22, 23, 24, 136, 137, 55, 84, 5, 86, 7, + 8, 10, 11, 4, 12, 148, 14, 15, 34, 35, + 56, 6, 20, 53, 54, 4, 55, 25, 26, 13, + 19, 19, 19, 31, 57, 33, 19, 21, 22, 23, + 24, 19, 56, 27, 6, 43, 44, 45, 46, 19, + 19, 49, 19, 0, 52, 143, 144, 145, 146, 147, + 1, 11, 126, 47, 126, 126, 50, 28, 124, -1, + 85, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 47, -1, -1, 50 + -1, -1, -1, -1, 172, 173, 174, 175, 176, 177, + 178, 138, 180, 140, 182, 183, 184, 185, 186, 187, + 188, 5, 190, 135, 8, 9, -1, 139, -1, -1, + -1, -1, 16, 17, 18, -1, -1, 149, -1, -1, + -1, -1, 26, -1, 28, -1, 30, -1, 32, -1, + -1, -1, 36, 37, 38, 39, 40, 41, 42, -1, + -1, -1, -1, -1, 48, -1, -1, 51 }; /* -*-C-*- Note some compilers choke on comments on `#line' lines. */ #line 3 "/sw/share/bison/bison.simple" @@ -1350,46 +1367,54 @@ case 18: case 19: #line 279 "parser.y" { - psmsg ("allow from: ", yyvsp[0].set[0].v.sval); - add_allowfrom (yyvsp[0].set[0].v.sval); + pimsg ("service header inspection: ", yyvsp[0].set[0].v.ival); + cur_service.inspection = yyvsp[0].set[0].v.ival; free (yyvsp[0].set); ; break;} case 20: #line 285 "parser.y" { - psmsg ("allow file: ", yyvsp[0].set[0].v.sval); - cur_service.allowfile = yyvsp[0].set[0].v.sval; + psmsg ("allow from: ", yyvsp[0].set[0].v.sval); + add_allowfrom (yyvsp[0].set[0].v.sval); free (yyvsp[0].set); ; break;} case 21: #line 291 "parser.y" { - psmsg ("deny from: ", yyvsp[0].set[0].v.sval); - add_denyfrom (yyvsp[0].set[0].v.sval); + psmsg ("allow file: ", yyvsp[0].set[0].v.sval); + cur_service.allowfile = yyvsp[0].set[0].v.sval; free (yyvsp[0].set); ; break;} case 22: #line 297 "parser.y" { - psmsg ("deny file: ", yyvsp[0].set[0].v.sval); - cur_service.denyfile = yyvsp[0].set[0].v.sval; + psmsg ("deny from: ", yyvsp[0].set[0].v.sval); + add_denyfrom (yyvsp[0].set[0].v.sval); free (yyvsp[0].set); ; break;} case 23: #line 303 "parser.y" { + psmsg ("deny file: ", yyvsp[0].set[0].v.sval); + cur_service.denyfile = yyvsp[0].set[0].v.sval; + free (yyvsp[0].set); + ; + break;} +case 24: +#line 309 "parser.y" +{ psmsg ("user account: ", yyvsp[0].set[0].v.sval); setuseraccount (yyvsp[0].set[0].v.sval); free (yyvsp[0].set[0].v.sval); free (yyvsp[0].set); ; break;} -case 24: -#line 310 "parser.y" +case 25: +#line 316 "parser.y" { pimsg ("converting backend statements, count is", yyvsp[0].n); for (i = 0; i < yyvsp[0].n; i++) @@ -1559,8 +1584,8 @@ case 24: memset (&cur_backend, 0, sizeof(cur_backend)); ; break;} -case 25: -#line 483 "parser.y" +case 26: +#line 489 "parser.y" { pimsg ("port statement:", lastnr); yyval.n = 1; @@ -1569,8 +1594,8 @@ case 25: yyval.set[0].v.ival = lastnr; ; break;} -case 26: -#line 495 "parser.y" +case 27: +#line 501 "parser.y" { psmsg ("bindto statement:", laststr); yyval.n = 1; @@ -1579,22 +1604,22 @@ case 26: yyval.set[0].v.sval = xstrdup(laststr); ; break;} -case 27: -#line 506 "parser.y" +case 28: +#line 512 "parser.y" { setlaststr (laststring); free (laststring); laststring = 0; ; break;} -case 28: -#line 515 "parser.y" +case 29: +#line 521 "parser.y" { setlastnr (SYMBOL); ; break;} -case 30: -#line 529 "parser.y" +case 31: +#line 535 "parser.y" { pimsg ("verbosity statement:", lastnr); yyval.n = 1; @@ -1603,26 +1628,26 @@ case 30: yyval.set[0].v.ival = lastnr; ; break;} -case 31: -#line 539 "parser.y" +case 32: +#line 545 "parser.y" { lastnr = 1; ; break;} -case 32: -#line 543 "parser.y" +case 33: +#line 549 "parser.y" { lastnr = 0; ; break;} -case 33: -#line 552 "parser.y" +case 34: +#line 558 "parser.y" { yyval = yyvsp[-2]; ; break;} -case 37: -#line 567 "parser.y" +case 38: +#line 573 "parser.y" { pimsg ("dispatch mode statement:", lastnr); yyval.n = 1; @@ -1637,14 +1662,14 @@ case 37: cur_service.name); ; break;} -case 38: -#line 584 "parser.y" +case 39: +#line 590 "parser.y" { setlastovernr (SYMBOL); ; break;} -case 39: -#line 590 "parser.y" +case 40: +#line 596 "parser.y" { psmsg ("external handler:", laststr); if (lastnr != ds_externalhandler) @@ -1653,64 +1678,64 @@ case 39: setlastext (laststr); ; break;} -case 40: -#line 601 "parser.y" +case 41: +#line 607 "parser.y" { yyval.n = 1; yyval.set = xmalloc (sizeof(Confset)); yyval.set[0].v.ival = lastnr; ; break;} -case 41: -#line 609 "parser.y" +case 42: +#line 615 "parser.y" { lastnr = ds_roundrobin; ; break;} -case 42: -#line 613 "parser.y" +case 43: +#line 619 "parser.y" { lastnr = ds_random; ; break;} -case 43: -#line 617 "parser.y" +case 44: +#line 623 "parser.y" { lastnr = ds_byduration; ; break;} -case 44: -#line 621 "parser.y" +case 45: +#line 627 "parser.y" { lastnr = ds_bysize; ; break;} -case 45: -#line 625 "parser.y" +case 46: +#line 631 "parser.y" { lastnr = ds_byorder; ; break;} -case 46: -#line 629 "parser.y" +case 47: +#line 635 "parser.y" { lastnr = ds_byconnections; ; break;} -case 47: -#line 633 "parser.y" +case 48: +#line 639 "parser.y" { lastnr = ds_externalhandler; ; break;} -case 48: -#line 637 "parser.y" +case 49: +#line 643 "parser.y" { lastnr = ds_byclientip; ; break;} -case 49: -#line 645 "parser.y" +case 50: +#line 651 "parser.y" { pimsg ("user account statement:", laststr); yyval.n = 1; @@ -1719,16 +1744,16 @@ case 49: yyval.set[0].v.sval = xstrdup (laststr); ; break;} -case 50: -#line 656 "parser.y" +case 51: +#line 662 "parser.y" { setlaststr (laststring); free (laststring); laststring = 0; ; break;} -case 51: -#line 666 "parser.y" +case 52: +#line 672 "parser.y" { pimsg ("reviving interval statement:", lastnr); yyval.n = 1; @@ -1737,8 +1762,8 @@ case 51: yyval.set[0].v.ival = lastnr; ; break;} -case 52: -#line 678 "parser.y" +case 53: +#line 684 "parser.y" { pimsg ("backlog statement:", lastnr); yyval.n = 1; @@ -1747,8 +1772,8 @@ case 52: yyval.set[0].v.ival = lastnr; ; break;} -case 53: -#line 690 "parser.y" +case 54: +#line 696 "parser.y" { pimsg ("shmkey statement:", lastnr); yyval.n = 1; @@ -1757,8 +1782,8 @@ case 53: yyval.set[0].v.ival = lastnr; ; break;} -case 54: -#line 702 "parser.y" +case 55: +#line 708 "parser.y" { pimsg ("connection timeout statement:", lastnr); yyval.n = 1; @@ -1767,8 +1792,8 @@ case 54: yyval.set[0].v.ival = lastnr; ; break;} -case 55: -#line 714 "parser.y" +case 56: +#line 720 "parser.y" { pimsg ("max clients statement (service):", lastnr); yyval.n = 1; @@ -1777,8 +1802,8 @@ case 55: yyval.set[0].v.ival = lastnr; ; break;} -case 56: -#line 726 "parser.y" +case 57: +#line 732 "parser.y" { pimsg ("service type:", lastnr); yyval.n = 1; @@ -1787,20 +1812,42 @@ case 56: yyval.set[0].v.ival = lastnr; ; break;} -case 58: -#line 741 "parser.y" +case 59: +#line 747 "parser.y" { lastnr = type_any; ; break;} -case 59: -#line 745 "parser.y" +case 60: +#line 751 "parser.y" { lastnr = type_http; ; break;} -case 60: -#line 753 "parser.y" +case 61: +#line 759 "parser.y" +{ + pimsg ("service header inspection: ", lastnr); + yyval.n = 1; + yyval.set = xmalloc (sizeof(Confset)); + yyval.set[0].cf = cf_inspectionspec; + yyval.set[0].v.ival = lastnr; + ; + break;} +case 63: +#line 774 "parser.y" +{ + lastnr = ins_deep; + ; + break;} +case 64: +#line 778 "parser.y" +{ + lastnr = ins_shallow; + ; + break;} +case 65: +#line 786 "parser.y" { psmsg ("allow from: ", laststr); yyval.n = 1; @@ -1809,8 +1856,8 @@ case 60: yyval.set[0].v.sval = xstrdup(laststr); ; break;} -case 61: -#line 765 "parser.y" +case 66: +#line 798 "parser.y" { psmsg ("allow from: ", laststr); yyval.n = 1; @@ -1819,8 +1866,8 @@ case 61: yyval.set[0].v.sval = xstrdup(laststr); ; break;} -case 62: -#line 777 "parser.y" +case 67: +#line 810 "parser.y" { psmsg ("allow file: ", laststr); yyval.n = 1; @@ -1829,8 +1876,8 @@ case 62: yyval.set[0].v.sval = xstrdup(laststr); ; break;} -case 63: -#line 789 "parser.y" +case 68: +#line 822 "parser.y" { psmsg ("allow file: ", laststr); yyval.n = 1; @@ -1839,22 +1886,22 @@ case 63: yyval.set[0].v.sval = xstrdup(laststr); ; break;} -case 64: -#line 800 "parser.y" +case 69: +#line 833 "parser.y" { setlaststr (laststring); free (laststring); laststring = 0; ; break;} -case 65: -#line 812 "parser.y" +case 70: +#line 845 "parser.y" { yyval = yyvsp[-1]; ; break;} -case 66: -#line 819 "parser.y" +case 71: +#line 852 "parser.y" { psmsg ("backend name:", SYMBOL); for (i = 0; i < cur_service.nbackend; i++) @@ -1864,8 +1911,8 @@ case 66: cur_backend.name = xstrdup (SYMBOL); ; break;} -case 67: -#line 831 "parser.y" +case 72: +#line 864 "parser.y" { yyvsp[-1].n++; yyvsp[-1].set = xrealloc (yyvsp[-1].set, yyvsp[-1].n * sizeof(Confset)); @@ -1873,153 +1920,153 @@ case 67: yyval = yyvsp[-1]; ; break;} -case 68: -#line 838 "parser.y" +case 73: +#line 871 "parser.y" { yyval = yyvsp[0]; ; break;} -case 69: -#line 845 "parser.y" +case 74: +#line 878 "parser.y" { yyval = yyvsp[0]; ; break;} -case 70: -#line 851 "parser.y" +case 75: +#line 884 "parser.y" { psmsg ("backend server:", yyvsp[0].set[0].v.sval); yyval = yyvsp[0]; ; break;} -case 71: -#line 856 "parser.y" +case 76: +#line 889 "parser.y" { pimsg ("backend port:", yyvsp[0].set[0].v.ival); yyval = yyvsp[0]; ; break;} -case 72: -#line 861 "parser.y" +case 77: +#line 894 "parser.y" { pimsg ("backend verbosity:", yyvsp[0].set[0].v.ival); yyval = yyvsp[0]; ; break;} -case 73: -#line 866 "parser.y" +case 78: +#line 899 "parser.y" { psmsg ("backend onstart:", yyvsp[0].set[0].v.sval); yyval = yyvsp[0]; ; break;} -case 74: -#line 871 "parser.y" +case 79: +#line 904 "parser.y" { psmsg ("backend onend:", yyvsp[0].set[0].v.sval); yyval = yyvsp[0]; ; break;} -case 75: -#line 876 "parser.y" +case 80: +#line 909 "parser.y" { psmsg ("backend onfail:", yyvsp[0].set[0].v.sval); yyval = yyvsp[0]; ; break;} -case 76: -#line 881 "parser.y" +case 81: +#line 914 "parser.y" { psmsg ("backend trafficlog:", yyvsp[0].set[0].v.sval); yyval = yyvsp[0]; ; break;} -case 77: -#line 886 "parser.y" +case 82: +#line 919 "parser.y" { psmsg ("backend trafficlog:", yyvsp[0].set[0].v.sval); yyval = yyvsp[0]; ; break;} -case 78: -#line 891 "parser.y" +case 83: +#line 924 "parser.y" { pimsg ("backend weight:", yyvsp[0].set[0].v.ival); yyval = yyvsp[0]; ; break;} -case 79: -#line 896 "parser.y" +case 84: +#line 929 "parser.y" { pimsg ("backend decay:", yyvsp[0].set[0].v.ival); yyval = yyvsp[0]; ; break;} -case 80: -#line 901 "parser.y" +case 85: +#line 934 "parser.y" { pimsg ("backend maxconnections:", yyvsp[0].set[0].v.ival); yyval = yyvsp[0]; ; break;} -case 81: -#line 906 "parser.y" +case 86: +#line 939 "parser.y" { psmsg ("backend sticky cookie:", yyvsp[0].set[0].v.sval); yyval = yyvsp[0]; ; break;} -case 82: -#line 911 "parser.y" +case 87: +#line 944 "parser.y" { psmsg ("addclientheader:", yyvsp[0].set[0].v.sval); yyval = yyvsp[0]; ; break;} -case 83: -#line 916 "parser.y" +case 88: +#line 949 "parser.y" { psmsg ("setclientheader:", yyvsp[0].set[0].v.sval); yyval = yyvsp[0]; ; break;} -case 84: -#line 921 "parser.y" +case 89: +#line 954 "parser.y" { psmsg ("appendclientheader:", yyvsp[0].set[0].v.sval); yyval = yyvsp[0]; ; break;} -case 85: -#line 926 "parser.y" +case 90: +#line 959 "parser.y" { psmsg ("addserverheader:", yyvsp[0].set[0].v.sval); yyval = yyvsp[0]; ; break;} -case 86: -#line 931 "parser.y" +case 91: +#line 964 "parser.y" { psmsg ("setserverheader:", yyvsp[0].set[0].v.sval); yyval = yyvsp[0]; ; break;} -case 87: -#line 936 "parser.y" +case 92: +#line 969 "parser.y" { psmsg ("appendserverheader:", yyvsp[0].set[0].v.sval); yyval = yyvsp[0]; ; break;} -case 88: -#line 941 "parser.y" +case 93: +#line 974 "parser.y" { pimsg ("backend retries:", yyvsp[0].set[0].v.ival); yyval = yyvsp[0]; ; break;} -case 89: -#line 951 "parser.y" +case 94: +#line 984 "parser.y" { psmsg ("server statement:", laststr); yyval.n = 1; @@ -2028,8 +2075,8 @@ case 89: yyval.set[0].v.sval = xstrdup (laststr); ; break;} -case 90: -#line 963 "parser.y" +case 95: +#line 996 "parser.y" { pimsg ("weight statement", lastnr); yyval.n = 1; @@ -2038,8 +2085,8 @@ case 90: yyval.set[0].v.ival = lastnr; ; break;} -case 91: -#line 975 "parser.y" +case 96: +#line 1008 "parser.y" { pimsg ("decay statement", lastnr); yyval.n = 1; @@ -2048,14 +2095,14 @@ case 91: yyval.set[0].v.ival = lastnr; ; break;} -case 92: -#line 985 "parser.y" +case 97: +#line 1018 "parser.y" { setlaststr (laststring); ; break;} -case 93: -#line 993 "parser.y" +case 98: +#line 1026 "parser.y" { pimsg ("retries:", lastnr); yyval.n = 1; @@ -2064,8 +2111,8 @@ case 93: yyval.set[0].v.ival = lastnr; ; break;} -case 94: -#line 1005 "parser.y" +case 99: +#line 1038 "parser.y" { psmsg ("onstart statement:", laststr); yyval.n = 1; @@ -2074,8 +2121,8 @@ case 94: yyval.set[0].v.sval = xstrdup (laststr); ; break;} -case 95: -#line 1017 "parser.y" +case 100: +#line 1050 "parser.y" { psmsg ("onfail statement:", laststr); yyval.n = 1; @@ -2084,8 +2131,8 @@ case 95: yyval.set[0].v.sval = xstrdup (laststr); ; break;} -case 96: -#line 1029 "parser.y" +case 101: +#line 1062 "parser.y" { psmsg ("onend statement:", laststr); yyval.n = 1; @@ -2094,8 +2141,8 @@ case 96: yyval.set[0].v.sval = xstrdup (laststr); ; break;} -case 97: -#line 1041 "parser.y" +case 102: +#line 1074 "parser.y" { psmsg ("trafficlog statement:", laststr); yyval.n = 1; @@ -2104,8 +2151,8 @@ case 97: yyval.set[0].v.sval = xstrdup (laststr); ; break;} -case 98: -#line 1053 "parser.y" +case 103: +#line 1086 "parser.y" { psmsg ("throughputlog statement:", laststr); yyval.n = 1; @@ -2114,24 +2161,24 @@ case 98: yyval.set[0].v.sval = xstrdup (laststr); ; break;} -case 99: -#line 1064 "parser.y" +case 104: +#line 1097 "parser.y" { setlaststr (laststring); free (laststring); laststring = 0; ; break;} -case 100: -#line 1073 "parser.y" +case 105: +#line 1106 "parser.y" { setlaststr (laststring); free (laststring); laststring = 0; ; break;} -case 101: -#line 1083 "parser.y" +case 106: +#line 1116 "parser.y" { psmsg ("insertcookie statement:", laststr); yyval.n = 1; @@ -2140,16 +2187,16 @@ case 101: yyval.set[0].v.sval = xstrdup (laststr); ; break;} -case 102: -#line 1094 "parser.y" +case 107: +#line 1127 "parser.y" { setlaststr (laststring); free (laststring); laststring = 0; ; break;} -case 103: -#line 1104 "parser.y" +case 108: +#line 1137 "parser.y" { psmsg ("addclientheader statement:", laststr); yyval.n = 1; @@ -2158,8 +2205,8 @@ case 103: yyval.set[0].v.sval = xstrdup (laststr); ; break;} -case 104: -#line 1116 "parser.y" +case 109: +#line 1149 "parser.y" { psmsg ("setclientheader statement:", laststr); yyval.n = 1; @@ -2168,8 +2215,8 @@ case 104: yyval.set[0].v.sval = xstrdup (laststr); ; break;} -case 105: -#line 1128 "parser.y" +case 110: +#line 1161 "parser.y" { psmsg ("appendclientheader statement:", laststr); yyval.n = 1; @@ -2178,8 +2225,8 @@ case 105: yyval.set[0].v.sval = xstrdup (laststr); ; break;} -case 106: -#line 1140 "parser.y" +case 111: +#line 1173 "parser.y" { psmsg ("addserverheader statement:", laststr); yyval.n = 1; @@ -2188,8 +2235,8 @@ case 106: yyval.set[0].v.sval = xstrdup (laststr); ; break;} -case 107: -#line 1152 "parser.y" +case 112: +#line 1185 "parser.y" { psmsg ("setserverheader statement:", laststr); yyval.n = 1; @@ -2198,8 +2245,8 @@ case 107: yyval.set[0].v.sval = xstrdup (laststr); ; break;} -case 108: -#line 1164 "parser.y" +case 113: +#line 1197 "parser.y" { psmsg ("appendserverheader statement:", laststr); yyval.n = 1; @@ -2208,118 +2255,124 @@ case 108: yyval.set[0].v.sval = xstrdup (laststr); ; break;} -case 109: -#line 1175 "parser.y" +case 114: +#line 1208 "parser.y" { setlaststr (laststring); free (laststring); laststring = 0; ; break;} -case 110: -#line 1182 "parser.y" +case 115: +#line 1215 "parser.y" { yyerrmsg = "HTTP header specifier expected"; ; break;} -case 111: -#line 1187 "parser.y" +case 116: +#line 1220 "parser.y" { yyerrmsg = "cookie specifier expected"; ; break;} -case 112: -#line 1192 "parser.y" +case 117: +#line 1225 "parser.y" { yyerrmsg = "number expected"; ; break;} -case 113: -#line 1197 "parser.y" +case 118: +#line 1230 "parser.y" { yyerrmsg = "hostname or IP address expected"; ; break;} -case 114: -#line 1202 "parser.y" +case 119: +#line 1235 "parser.y" { yyerrmsg = "'service' expected"; ; break;} -case 115: -#line 1207 "parser.y" +case 120: +#line 1240 "parser.y" { yyerrmsg = "backend definition statement expected"; ; break;} -case 116: -#line 1212 "parser.y" +case 121: +#line 1245 "parser.y" { yyerrmsg = "service body statement expected"; ; break;} -case 117: -#line 1217 "parser.y" +case 122: +#line 1250 "parser.y" { yyerrmsg = "semicolon (;) expected"; ; break;} -case 118: -#line 1222 "parser.y" +case 123: +#line 1255 "parser.y" { yyerrmsg = "'on' or 'off' expetcted"; ; break;} -case 119: -#line 1227 "parser.y" +case 124: +#line 1260 "parser.y" { yyerrmsg = "dispatch method expected"; ; break;} -case 120: -#line 1232 "parser.y" +case 125: +#line 1265 "parser.y" { yyerrmsg = "command line expected"; ; break;} -case 121: -#line 1237 "parser.y" +case 126: +#line 1270 "parser.y" { yyerrmsg = "file name expected"; ; break;} -case 122: -#line 1242 "parser.y" +case 127: +#line 1275 "parser.y" { yyerrmsg = "service name (identifier) expected"; ; break;} -case 123: -#line 1247 "parser.y" +case 128: +#line 1280 "parser.y" { yyerrmsg = "backend name (identifier) expected"; ; break;} -case 124: -#line 1252 "parser.y" +case 129: +#line 1285 "parser.y" { - yyerrmsg = "IP address or 'any' expected"; + yyerrmsg = "IP address such as 1.2.3.4 or 'any' expected"; ; break;} -case 125: -#line 1257 "parser.y" +case 130: +#line 1290 "parser.y" { yyerrmsg = "Service type expected ('any', 'stickyhttp', ...)"; ; break;} -case 126: -#line 1262 "parser.y" +case 131: +#line 1295 "parser.y" +{ + yyerrmsg = "Header inspection mode mode expected ('shallow' or 'deep')"; +; + break;} +case 132: +#line 1300 "parser.y" { yyerrmsg = "IP filter(s) expected"; ; break;} -case 127: -#line 1267 "parser.y" +case 133: +#line 1305 "parser.y" { yyerrmsg = "username expected"; ; @@ -2557,4 +2610,4 @@ yyreturn: #endif return yyresult; } -#line 1271 "parser.y" +#line 1309 "parser.y" diff --git a/src/lib/parser.h b/src/lib/parser.h @@ -54,6 +54,9 @@ # define USERACCOUNT 303 # define BYCLIENTIP 304 # define RETRIES 305 +# define HEADERINSPECTION 306 +# define DEEP 307 +# define SHALLOW 308 extern YYSTYPE yylval; diff --git a/src/lib/parser.y b/src/lib/parser.y @@ -137,7 +137,7 @@ static void setuseraccount (char *username) { STICKYCOOKIE ADDCLIENTHEADER SETCLIENTHEADER APPENDCLIENTHEADER ADDSERVERHEADER SETSERVERHEADER APPENDSERVERHEADER ALLOWFROM DENYFROM ALLOWFILE DENYFILE EXTERNALHANDLER ONEND - USERACCOUNT BYCLIENTIP RETRIES + USERACCOUNT BYCLIENTIP RETRIES HEADERINSPECTION DEEP SHALLOW %% /* Config file grammar rules */ @@ -276,6 +276,12 @@ servicebody: free ($1.set); } | + inspectionstatement { + pimsg ("service header inspection: ", $1.set[0].v.ival); + cur_service.inspection = $1.set[0].v.ival; + free ($1.set); + } +| allowfromstatement { psmsg ("allow from: ", $1.set[0].v.sval); add_allowfrom ($1.set[0].v.sval); @@ -747,6 +753,33 @@ typespecifier: } ; +inspectionstatement: + HEADERINSPECTION + shallowdeepspec + semicol { + pimsg ("service header inspection: ", lastnr); + $$.n = 1; + $$.set = xmalloc (sizeof(Confset)); + $$.set[0].cf = cf_inspectionspec; + $$.set[0].v.ival = lastnr; + } +; + +shallowdeepspec: + shallowdeep_expected + shallowdeepspecifier + ; + +shallowdeepspecifier: + DEEP { + lastnr = ins_deep; + } +| + SHALLOW { + lastnr = ins_shallow; + } +; + allowfromstatement: ALLOWFROM ipfilters @@ -1250,7 +1283,7 @@ backendname_expected: { ; ipaddress_expected: { - yyerrmsg = "IP address or 'any' expected"; + yyerrmsg = "IP address such as 1.2.3.4 or 'any' expected"; } ; @@ -1259,6 +1292,11 @@ type_expected: { } ; +shallowdeep_expected: { + yyerrmsg = "Header inspection mode mode expected ('shallow' or 'deep')"; +} +; + ipfilters_expected: { yyerrmsg = "IP filter(s) expected"; } diff --git a/src/lib/parserclose.c b/src/lib/parserclose.c @@ -1,5 +1,5 @@ /************************************************************************* - * This file is part of Crosroads 1.44, a load balancer and fail over + * This file is part of Crosroads 1.45, 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.44, a load balancer and fail over + * This file is part of Crosroads 1.45, 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.44, a load balancer and fail over + * This file is part of Crosroads 1.45, 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.44, a load balancer and fail over + * This file is part of Crosroads 1.45, a load balancer and fail over * utility for TCP. Copyright (c) Karel Kubat, distributed under GPL. * Visit http://crossroads.e-tunity.com for information. *************************************************************************/ @@ -15,8 +15,8 @@ void parser_open (char const *name) { /* "name" or <name> is converted to name */ actual = xstrdup (name); cp = actual + strlen(actual) - 1; - if (*actual == '"' && *cp == '"' || - *actual == '<' && *cp == '>') { + if ( (*actual == '"' && *cp == '"') || + (*actual == '<' && *cp == '>') ) { *cp = 0; strcpy (actual, actual + 1); } @@ -31,7 +31,7 @@ void parser_open (char const *name) { if (nparserstate > 0) { parserstate[nparserstate - 1].lineno = yylineno; msg ("%d bytes remain in configuration %s beyond line %d", - strlen(parserstate[nparserstate - 1].buf), + (int) strlen(parserstate[nparserstate - 1].buf), parserstate[nparserstate - 1].name, yylineno); } diff --git a/src/lib/parserrun.c b/src/lib/parserrun.c @@ -1,5 +1,5 @@ /************************************************************************* - * This file is part of Crosroads 1.44, a load balancer and fail over + * This file is part of Crosroads 1.45, 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.44, a load balancer and fail over + * This file is part of Crosroads 1.45, 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.44, a load balancer and fail over + * This file is part of Crosroads 1.45, 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.44, a load balancer and fail over + * This file is part of Crosroads 1.45, 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.44, a load balancer and fail over + * This file is part of Crosroads 1.45, a load balancer and fail over * utility for TCP. Copyright (c) Karel Kubat, distributed under GPL. * Visit http://crossroads.e-tunity.com for information. *************************************************************************/ @@ -37,7 +37,7 @@ void runservice () { } /* Child branch */ - set_program_title ("Service %s: listening", activeservice->name); + setproctitle ("crossroads - Service %s: listening", activeservice->name); close (0); close (1); close (2); diff --git a/src/lib/serve.c b/src/lib/serve.c @@ -1,5 +1,5 @@ /************************************************************************* - * This file is part of Crosroads 1.44, a load balancer and fail over + * This file is part of Crosroads 1.45, 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 @@ -0,0 +1,59 @@ +/************************************************************************* + * This file is part of Crosroads 1.45, 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" + +/* This defines setproctitle() incase your system lacks it. */ + +#if HAVE_SETPROCTITLE == 0 + +extern char **environ; + +void setproctitle (char const *fmt, ...) { +#if SET_PROC_TITLE_BY_ARGV == 1 + int i; + char buf[SPT_BUFSIZE], **envp; + va_list ap; + static int argv_lth = -1; + + if (argv_lth == -1) { + /* First time around. Save the environment, initialize. */ + envp = environ; + for (i = 0; envp[i]; i++) + ; + environ = xmalloc (sizeof(char*) * (i + 1)); + for (i = 0; envp[i]; i++) + environ[i] = xstrdup(envp[i]); + environ[i] = 0; + + if (i) + argv_lth = envp[i - 1] + strlen(envp[i - 1]) - org_argv[0]; + else + argv_lth = org_argv[org_argc - 1] + + strlen(org_argv[org_argc - 1]) - org_argv[0]; + } + + /* Prepare the new commandline */ + va_start (ap, fmt); + vsnprintf (buf, SPT_BUFSIZE, fmt, ap); + va_end (ap); + + /* Determine max length */ + i = strlen (buf); + if (i > argv_lth - 2) { + i = argv_lth - 2; + buf[i] = 0; + } + + /* Set into original argv[0] */ + memset (org_argv[0], 0, argv_lth); + strcpy (org_argv[0], buf); + org_argv[1] = 0; +#endif /* SET_PROC_TITLE_BY_ARGV */ +} + +#endif /* HAVE_SETPROCTITLE */ + diff --git a/src/lib/setprogramtitle.c b/src/lib/setprogramtitle.c @@ -1,42 +0,0 @@ -/************************************************************************* - * This file is part of Crosroads 1.44, 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" - -void set_program_title (char const *fmt, ...) { -# if SET_PROC_TITLE_BY_ARGV == 1 - - static int orglen; - char *title, *name = "crossroads"; - int i, j, k; - va_list args; - - /* Make the title */ - va_start (args, fmt); - title = str_vprintf (fmt, args); - va_end (args); - - /* Reset old argv, count max length */ - if (! orglen) - for (i = 0; i < org_argc; i++) - orglen += (strlen(org_argv[i]) + 1); - - /* Paste in our program name first */ - for (i = 0; i <= (int) strlen(name) && i < orglen; i++) - org_argv[0][i] = name[i]; - - /* Paste in the new title */ - for (j = 0; j < (int) strlen(title) && i + j < orglen; j++) - org_argv[0][i + j] = title[j]; - - /* Reset remainder of old cmd line */ - for (k = i + j; k < orglen; k++) - org_argv[0][k] = 0; - - /* Free up */ - free (title); - -# endif /* SET_PROC_TITLE_BY_ARGV */ -} diff --git a/src/lib/showconfig.c b/src/lib/showconfig.c @@ -1,5 +1,5 @@ /************************************************************************* - * This file is part of Crosroads 1.44, a load balancer and fail over + * This file is part of Crosroads 1.45, a load balancer and fail over * utility for TCP. Copyright (c) Karel Kubat, distributed under GPL. * Visit http://crossroads.e-tunity.com for information. *************************************************************************/ @@ -24,9 +24,11 @@ void show_config () { "DNS_CACHETTL default ttl of cached DNS: %d\n" "CONNECT_TIMEOUT backend connect timeout: %d\n" "RETRY_WAIT backend retry pause: %d\n" - "TCP_BUFSZ network buffer size: %d\n" + "DEFAULT_TCP_BUFSZ default network buffer size: %d\n" "PREFIX installation tree prefix: %s\n" "BINDIR directory for binaries: %s\n" + "DEFAULT_SPT_BUFSIZE default cmdline length: %d\n" + "SPT_BUFSIZE used cmdline length: %d\n" "SET_PROC_TITLE_BY_ARGV argv assumed linear array: %d\n" "EXTRALIBS extra library dependencies: %s\n" "LIBS standard library dependencies: %s\n" @@ -35,14 +37,16 @@ void show_config () { MAINTAINEREMAIL, DEFAULT_CONF, MAX_BACKEND, SLEEP_TIME, DEF_MAX, DNS_CACHESIZE, DNS_CACHETTL, - CONNECT_TIMEOUT, RETRY_WAIT, TCP_BUFSZ, PREFIX, BINDIR, + CONNECT_TIMEOUT, RETRY_WAIT, DEFAULT_TCP_BUFSZ, PREFIX, BINDIR, + DEFAULT_SPT_BUFSIZE, SPT_BUFSIZE, SET_PROC_TITLE_BY_ARGV, EXTRALIBS, LIBS); - SHOWDEF (HAVE_MALLOC_H, "HAVE_MALLOC_H", "<malloc.h> present:"); - SHOWDEF (HAVE_STDINT_H, "HAVE_STDINT_H", "<stdint.h> present:"); - SHOWDEF (HAVE_FLOCK, "HAVE_FLOCK", "flock() present:"); - SHOWDEF (HAVE_LOCKF, "HAVE_LOCKF", "lockf() present:"); - SHOWDEF (HAVE_STRLCAT, "HAVE_STRLCAT", "strlcat() present:"); - SHOWDEF (HAVE_SRANDDEV, "HAVE_SRANDDEV", "sranddev() present:"); - SHOWDEF (HAVE_VSYSLOG, "HAVE_VSYSLOG", "vsyslog() present:"); - SHOWDEF (HAVE_STRCASESTR, "HAVE_STRCASESTR", "strcasestr() present:"); + SHOWDEF (HAVE_MALLOC_H, "HAVE_MALLOC_H", "<malloc.h> present:"); + SHOWDEF (HAVE_STDINT_H, "HAVE_STDINT_H", "<stdint.h> present:"); + SHOWDEF (HAVE_FLOCK, "HAVE_FLOCK", "flock() present:"); + SHOWDEF (HAVE_LOCKF, "HAVE_LOCKF", "lockf() present:"); + SHOWDEF (HAVE_STRLCAT, "HAVE_STRLCAT", "strlcat() present:"); + SHOWDEF (HAVE_SRANDDEV, "HAVE_SRANDDEV", "sranddev() present:"); + SHOWDEF (HAVE_VSYSLOG, "HAVE_VSYSLOG", "vsyslog() present:"); + SHOWDEF (HAVE_STRCASESTR, "HAVE_STRCASESTR", "strcasestr() present:"); + SHOWDEF (HAVE_SETPROCTITLE, "HAVE_SETPROCTITLE", "setproctitle() present:"); } diff --git a/src/lib/showservices.c b/src/lib/showservices.c @@ -1,5 +1,5 @@ /************************************************************************* - * This file is part of Crosroads 1.44, a load balancer and fail over + * This file is part of Crosroads 1.45, 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,5 +1,5 @@ /************************************************************************* - * This file is part of Crosroads 1.44, a load balancer and fail over + * This file is part of Crosroads 1.45, 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/stagetostring.c b/src/lib/stagetostring.c @@ -1,5 +1,5 @@ /************************************************************************* - * This file is part of Crosroads 1.44, a load balancer and fail over + * This file is part of Crosroads 1.45, 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.44, a load balancer and fail over + * This file is part of Crosroads 1.45, 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.44, a load balancer and fail over + * This file is part of Crosroads 1.45, 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.44, a load balancer and fail over + * This file is part of Crosroads 1.45, 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.44, a load balancer and fail over + * This file is part of Crosroads 1.45, 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.44, a load balancer and fail over + * This file is part of Crosroads 1.45, 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.44, a load balancer and fail over + * This file is part of Crosroads 1.45, 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.44, a load balancer and fail over + * This file is part of Crosroads 1.45, 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.44, a load balancer and fail over + * This file is part of Crosroads 1.45, 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.44, a load balancer and fail over + * This file is part of Crosroads 1.45, 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.44, a load balancer and fail over + * This file is part of Crosroads 1.45, 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.44, a load balancer and fail over + * This file is part of Crosroads 1.45, 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.44, a load balancer and fail over + * This file is part of Crosroads 1.45, 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.44, a load balancer and fail over + * This file is part of Crosroads 1.45, 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.44, a load balancer and fail over + * This file is part of Crosroads 1.45, a load balancer and fail over * utility for TCP. Copyright (c) Karel Kubat, distributed under GPL. * Visit http://crossroads.e-tunity.com for information. *************************************************************************/ @@ -23,7 +23,8 @@ void tcpserve (int server_sock) { if ( (pid = fork()) < 0 ) error ("Fork failed: %s", strerror(errno)); else if (!pid) { - set_program_title ("Service %s: wakeup", activeservice->name); + setproctitle ("crossroads - Service %s: wakeup", + activeservice->name); wakeup_handler(); } else { msg ("Service %s: started wakeup handler at pid %d", diff --git a/src/lib/tellservice.c b/src/lib/tellservice.c @@ -1,5 +1,5 @@ /************************************************************************* - * This file is part of Crosroads 1.44, a load balancer and fail over + * This file is part of Crosroads 1.45, 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/thruputlog.c b/src/lib/thruputlog.c @@ -1,5 +1,5 @@ /************************************************************************* - * This file is part of Crosroads 1.44, a load balancer and fail over + * This file is part of Crosroads 1.45, 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.44, a load balancer and fail over + * This file is part of Crosroads 1.45, 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.44, a load balancer and fail over + * This file is part of Crosroads 1.45, 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.44, a load balancer and fail over + * This file is part of Crosroads 1.45, 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.44, a load balancer and fail over + * This file is part of Crosroads 1.45, 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,15 +1,17 @@ /************************************************************************* - * This file is part of Crosroads 1.44, a load balancer and fail over + * This file is part of Crosroads 1.45, 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" #include "usage.h" void usage () { fprintf (stderr, "\n" USAGETEXT "\n", VER, AUTHORNAME, YEARS, MAINTAINERNAME, MAINTAINEREMAIL, + DEFAULT_TCP_BUFSZ, DEFAULT_CONF, DNS_CACHETTL); exit (1); } diff --git a/src/lib/usage.txt b/src/lib/usage.txt @@ -19,9 +19,10 @@ Usage: crossroads [flags] services: show the configured services Supported flags: - -a: logs starting and finishing activity to syslog - -b writes binary configuration to stdout (debugging only) - -C: shows compile-time configuration and stops + -a: Logs starting and finishing activity to syslog + -b Writes binary configuration to stdout (debugging only) + -B BUFSZ Defines the network buffer size, default %d bytes + -C: Shows compile-time configuration and stops -c CONFIG: Uses the named configuration, instead of the default %s -d TTL: Specifies the time to live of cached DNS entries, diff --git a/src/lib/vsyslog.c b/src/lib/vsyslog.c @@ -1,5 +1,5 @@ /************************************************************************* - * This file is part of Crosroads 1.44, a load balancer and fail over + * This file is part of Crosroads 1.45, 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.44, a load balancer and fail over + * This file is part of Crosroads 1.45, 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.44, a load balancer and fail over + * This file is part of Crosroads 1.45, 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.44, a load balancer and fail over + * This file is part of Crosroads 1.45, 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.44, a load balancer and fail over + * This file is part of Crosroads 1.45, 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.44, a load balancer and fail over + * This file is part of Crosroads 1.45, 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.44, a load balancer and fail over + * This file is part of Crosroads 1.45, 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.44, a load balancer and fail over + * This file is part of Crosroads 1.45, 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.44, a load balancer and fail over + * This file is part of Crosroads 1.45, 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.44, a load balancer and fail over + * This file is part of Crosroads 1.45, 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, "b?c:fhvi:Val:stCm:xd:")) > 0 ) + while ( (opt = getopt (argc, argv, "bB?c:fhvi:Val:stCm:xd:")) > 0 ) switch (opt) { case 'a': log_activity++; @@ -20,6 +20,9 @@ exit (0); #endif break; + case 'B': + tcp_bufsz = atoi (optarg); + break; case 'c': config_file = optarg; break; diff --git a/tools/c-conf b/tools/c-conf @@ -4,7 +4,8 @@ use strict; use Getopt::Std; # Globals -my $VER = "1.08"; +my $VER = "1.09"; +# 1.09 [KK 2007-06-13] Added 'lib64' variants to libdirs, for 64bit Linux # 1.08 [KK 2007-05-22] -L{dir} shown only once for identical dirs during 'lib' # 1.07 [KK 2007-05-18] Flag -c for caching implemented # 1.06 [KK 2007-04-27] Added ifheader01 and libfunction01 @@ -24,7 +25,9 @@ my @def_headerdirs = ('/usr/include', "$ENV{HOME}/include", ); my @def_libdirs = ('/usr/lib', + '/usr/lib64', '/usr/local/lib', + '/usr/local/lib64', '/usr/ucblib', "$ENV{HOME}/lib", );