commit e137d345f47aee2f571d0f852fb9cfef6590d8bf parent 876509ed901eacfcd3fa103d76a6e09148f8c62a Author: finwo <finwo@pm.me> Date: Sat, 3 Jan 2026 19:34:35 +0100 1.75 Diffstat:
156 files changed, 3664 insertions(+), 2316 deletions(-)
diff --git a/ChangeLog b/ChangeLog @@ -1,6 +1,45 @@ + ChangeLog for Crossroads ------------------------------------------------------------------------------ +1.75 [KK 2008-01-25] + - Changed chunked transfer copying in HTTP mode. The trailing + \r\n, following a zero-bytes chunk, also gets handled in + http_copy(). Before it was left for handling in a next loop. + - Bugfix in the parser, regarding handling of external dispatcher + definitions. + - Change in the way Crossroads handles responses from external + dispatchers: when no back ends are available, XR will sleep for + a short time. Better handling of incorrect responses. + - Irritating svn messages during build phase suppressed. + +1.74 [KK 2008-01-22] + - Bugfix in HTTP header scanning. + - strnstr() added for systems that lack it + - Warning stanza enhanced when select() fails during network writes, + back end names are displayed + +1.73 [KK 2008-01-17] + - Upon service startup the initial configuration is logged (if + verbose is on). + - Flag -P added for parser/lexer verbosity (debugging only). + <stringstate> rewritten. String-state lexer strips trailing + spaces in stringstate mode. + - Backend-level directive "httptiminglog" implemented. + - "througputlog" logging will also include the # of bytes. + +1.72 [KK 2008-01-14] + - Lexical analyzer changed: whitespace leading up to strings (eg. + external handler specifiiers) are skipped. + - Porting issues with Intel Macs solved. + - Upped c-conf to 1.11 (compatible with MacOSX's extensions + MacPorts and with Fink). + - External dispatchers are called even when NO back ends are + available. Previously asking an external dispatcher would only + occur when one or more back ends was up. Furthermore, + Crossroads will always accept the dispatcher's suggestion, even + when that back end was previously unavailable. + 1.71 [KK 2008-01-12] - Bugfix in 1.70 related to HTTP body copy-thru mode. diff --git a/Makefile b/Makefile @@ -7,8 +7,10 @@ include etc/Makefile.def foo: @cat etc/Makefile.help -local: +compile-only: BASE=$(BASE) $(MAKE) -C src + +local: compile-only BASE=$(BASE) $(MAKE) -C test local-pg: diff --git a/doc/crossroads.1 b/doc/crossroads.1 @@ -112,7 +112,7 @@ using \fBverbosity\fP statements in the configuration\&.) \fB-V\fP: Shows the version ID and stops\&. .IP .IP o -\fB-?, -h\fP: Shows an overview of the usage\&. +\fB-?\fP: Shows an overview of the usage\&. .PP .SH "FILES" \fB/etc/crossroads\&.conf\fP, the default configuration file diff --git a/doc/crossroads.conf.7 b/doc/crossroads.conf.7 @@ -22,10 +22,28 @@ all settings do\&. This section describes the general elements of the crossroads configuration language\&. .PP -\fBEmpty lines and comments\fP +\fBEmpty lines, indentation and comments\fP .PP -Empty lines are of course allowed in the -configuration\&. Crossroads recognizes three formats of comment: +Empty lines are of course allowed in the configuration\&. Also, +indentation is irrelevant as far as processing is concerned, but is +loosely inspired on a C-like style\&. So the following two examples are +identical as far as Crossroads is concerned (thought the first one +will be typically more readable): +.PP +.nf +/* Example one */ +options { + tcpbuffersize 10240; + logactivity on; +} + +/* Example two */ +options {tcpbuffersize 10240 +;logactivity on;} +.fi + +.PP +Crossroads recognizes the following comment formats: .PP .IP o C-style, between \f(CW/*\fP and \f(CW*/\fP, @@ -127,6 +145,7 @@ grammar is: \f(CWbacklog\fP \f(CWthroughputlog\fP \f(CWtrafficlog\fP +\f(CWhttptiminglog\fP \f(CWstickycookie\fP \f(CWaddclientheader\fP \f(CWsetclientheader\fP @@ -148,6 +167,14 @@ grammar is: \f(CWavailable\fP \f(CWunavailable\fP \f(CWdown\fP +\f(CWoptions\fP +\f(CWlogactivity\fP +\f(CWtcpbuffersize\fP +\f(CWdnscachettl\fP +\f(CWlogfacility\fP +\f(CWshmpermissions\fP +\f(CWsloppyportbind\fP +\f(CWleaveprocesstitle\fP .PP Many keywords require an \fIidentifier\fP as the argument\&. E\&.g, a service has a unique name, which must start with a letter or @@ -157,7 +184,8 @@ digits\&. E\&.g\&., in the statement \f(CWservice myservice\fP, the keyword is .PP Other keywords require a numeric argument\&. Crossroads knows only non-negative integer numbers, as in \f(CWport 8000\fP\&. Here, \f(CWport\fP is -the keyword and \f(CW8000\fP is the number\&. +the keyword and \f(CW8000\fP is the number\&. Octal numbers are specified by +prefixing a zero; e\&.g\&., \f(CW0644\fP is an octal number\&. .PP Yet other keywords require \&'generic strings\&', such as hostname specifications or system commands\&. Such generic strings contain any @@ -180,6 +208,70 @@ Finally, an argument can be a \&'boolean\&' value\&. Crossroads knows \f(CWtrue\fP, \f(CWyes\fP and \f(CWon\fP all mean the same and can be used interchangeably; as can the keywords \f(CWfalse\fP, \f(CWno\fP and \f(CWoff\fP\&. .PP +.SH "Daemon options" + +.PP +Crossroads supports an optional block that defines run options for the +daemon process\&. These options can be also be specified on the command line +using flags\&. +.PP +The syntax of the options block is: +.PP +.nf +options { + \&. + \&. option statements (see below) + \&. +} +.fi + +.PP +In the curly-brace block the following option statements can occur: +.PP +.IP o +\f(CWlogactivity on;\fP or \f(CWoff\fP Turns activity logging on +or off\&. This is also controlled using the flag \f(CW-a\fP\&. The +default is not to log network activity\&. +.IP +.IP o +\f(CWtcpbuffersize\fP \fInumber\fP \f(CW;\fP This defines the size +of network buffers\&. The default is 5120 bytes\&. This is also +controlled using the flag \f(CW-B\fP\&. +.IP +.IP o +\f(CWdnscachettl\fP \fInumber\fP \f(CW;\fP This controls the +time-to-live of cached DNS entries, in seconds\&. Value zero +means no caching and is the default\&. This is also controlled +using the flag \f(CW-d\fP\&. +.IP +.IP o +\f(CWlogfacility\fP \fInumber\fP \f(CW;\fP This controls the +logging facility\&. Values 0 to 7 select \f(CWLOG_LOCAL0\fP to +\f(CWLOG_LOCAL7\fP\&. Any other value selects \f(CWLOG_DAEMON\fP, which +is also the default\&. This is also controlled using the flag \f(CW-l\fP\&. +.IP +.IP o +\f(CWshmpermissions\fP \f(CWnumber\fP \f(CW;\fP This defines the +permissions (for user, group and other) of the shared memory +block\&. The number is most often specified as an octal value, +e\&.g\&. \f(CW0644\fP, which is also the default\&. This is also +controlled using the flag \f(CW-m\fP\&. +.IP +.IP o +\f(CWsloppyportbind on;\fP or \f(CWoff\fP Turns on \&'sloppy\&' port +binding of the listener\&. When \f(CWon\fP, Crossroads will not +treat port-busy conditions as fatal, but will wait and retry\&. +The default is \f(CWoff\fP\&. This is also controlled using flag +\f(CW-s\fP\&. +.IP +.IP o +\f(CWleaveprocesstitle\fP \f(CWon;\fP or \f(CWoff\fP When \f(CWon\fP, the +process title of Crossroads is not modified, so that \f(CWps\fP +will show \f(CWcrossroads-daemon\fP\&. The default is \f(CWoff\fP: +Crosroads will modify its process name into something like +\fIcrossroads - Sevice web: listening\fP or \fIcrossroads - +Service web: serving\fP\&. +.PP .SH "Service definitions" .PP @@ -457,6 +549,10 @@ established connections that may be active within one service\&. Service (DOS) attacks\&. Without a limit, numerous network connections may spawn so many server instances, that the service ultimately breaks down and becomes unavailable\&. +.IP +Note that \f(CWmaxconnections\fP is also allowed in a backend +description block, in which case it limits the number of TCP +connections to that particular back end\&. .IP "Syntax:" \f(CWmaxconnections\fP \fInumber\fP, where the number specifies the maximum of concurrent connections to the service\&. @@ -722,6 +818,20 @@ unavailable\&. connection\&. .PP +\fBmaxconnections - Limiting the connections to a back end\fP +.IP "Description:" +The directive \f(CWmaxconnections\fP can also occur on the level of +back ends\&. In this case it limits the number of allowed +connections to this client\&. +.IP +Note that this directive can also occur on the level of a service +block, in which case it limits the overall number of connections\&. +.IP "Syntax:" +\f(CWmaxconnections\fP \fInumber\fP \f(CW;\fP +.IP "Default:" +0; meaning no limit + +.PP \fBweight - When a back end is more equal than others\fP .IP "Description:" To influence how backends are selected, a backend can specify its @@ -893,12 +1003,33 @@ depending on whether the information was received from the back end or from the client\&. .IP The \f(CWthroughputlog\fP statement writes shorthand transmissions to -its log, accompanied by timings\&. +its log, accompanied by timings and the number of bytes each +transmission was able to read or write in one chunk\&. +.IP "Syntax:" +The syntax is: +.IP +.IP o +\f(CWtrafficlog\fP \fIfilename\fP \f(CW;\fP +.IP o +\f(CWthroughputlog\fP \fIfilename\fP \f(CW;\fP +.IP "Default:" +none + +.PP +\fBhttptiminglog - Timing debugging in HTTP mode\fP +.IP "Description:" +The directive \f(CWhttptiminglog\fP turns on logging of HTTP mode +timing\&. There must be one argument, the filename where the timings +are written to\&. Turning on this option will slow down processing, +but may be helpful in finding out where delays are caused\&. .IP "Syntax:" +The syntax is: +.IP .IP o -\f(CWtrafficlog\fP \fIfilename\fP +\f(CWhttptiminglog\fP \fIfilename\fP \f(CW;\fP .IP o -\f(CWthroughputlog\fP \fIfilename\fP +Where \fIfilename\fP is the output file, e\&.g\&. +\f(CW/tmp/timings\&.log\fP .IP "Default:" none 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.71</title> +<title>Crossroads 1.75</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.71</h1> +<h1>Crossroads 1.75</h1> <h2>Karel Kubat <br> Maintained by Karel Kubat (karel@kubat.nl)</h2> @@ -60,121 +60,124 @@ <dl> <dt><a href="#l22">4.1: General language elements</a></dt> <dl> -<dt><a href="#l23">4.1.1: Empty lines and comments</a></dt> +<dt><a href="#l23">4.1.1: Empty lines, indentation and comments</a></dt> <dt><a href="#l24">4.1.2: Preprocessor directives</a></dt> <dt><a href="#l25">4.1.3: Keywords, numbers, identifiers, generic strings</a></dt> </dl> -<dt><a href="#l26">4.2: Service definitions</a></dt> +<dt><a href="#l26">4.2: Daemon options</a></dt> +<dt><a href="#l27">4.3: Service definitions</a></dt> <dl> -<dt><a href="#l27">4.2.1: port - Specifying the listen port</a></dt> -<dt><a href="#l28">4.2.2: type - Defining the service type</a></dt> -<dt><a href="#l29">4.2.3: headerinspection - are all HTTP headers inspected</a></dt> -<dt><a href="#l30">4.2.4: bindto - Binding to a specific IP address</a></dt> -<dt><a href="#l31">4.2.5: verbosity - Controlling debug output</a></dt> -<dt><a href="#l32">4.2.6: dispatchmode - How are back ends selected</a></dt> -<dt><a href="#l33">4.2.7: revivinginterval - Back end wakeup calls</a></dt> -<dt><a href="#l34">4.2.8: checkinterval - Periodic back end checks</a></dt> -<dt><a href="#l35">4.2.9: maxconnections - Limiting concurrent clients at service level</a></dt> -<dt><a href="#l36">4.2.10: backlog - The TCP Back Log size</a></dt> -<dt><a href="#l37">4.2.11: shmkey - Shared Memory Access</a></dt> -<dt><a href="#l38">4.2.12: allow* and deny* - Allowing or denying connections</a></dt> -<dt><a href="#l39">4.2.13: useraccount - Limiting the effective ID of external processes</a></dt> +<dt><a href="#l28">4.3.1: port - Specifying the listen port</a></dt> +<dt><a href="#l29">4.3.2: type - Defining the service type</a></dt> +<dt><a href="#l30">4.3.3: headerinspection - are all HTTP headers inspected</a></dt> +<dt><a href="#l31">4.3.4: bindto - Binding to a specific IP address</a></dt> +<dt><a href="#l32">4.3.5: verbosity - Controlling debug output</a></dt> +<dt><a href="#l33">4.3.6: dispatchmode - How are back ends selected</a></dt> +<dt><a href="#l34">4.3.7: revivinginterval - Back end wakeup calls</a></dt> +<dt><a href="#l35">4.3.8: checkinterval - Periodic back end checks</a></dt> +<dt><a href="#l36">4.3.9: maxconnections - Limiting concurrent clients at service level</a></dt> +<dt><a href="#l37">4.3.10: backlog - The TCP Back Log size</a></dt> +<dt><a href="#l38">4.3.11: shmkey - Shared Memory Access</a></dt> +<dt><a href="#l39">4.3.12: allow* and deny* - Allowing or denying connections</a></dt> +<dt><a href="#l40">4.3.13: useraccount - Limiting the effective ID of external processes</a></dt> </dl> -<dt><a href="#l40">4.3: Backend definitions</a></dt> +<dt><a href="#l41">4.4: Backend definitions</a></dt> <dl> -<dt><a href="#l41">4.3.1: server - Specifying the back end address</a></dt> -<dt><a href="#l42">4.3.2: port - Specifying a back end port</a></dt> -<dt><a href="#l43">4.3.3: verbosity - Controlling verbosity at the back end level</a></dt> -<dt><a href="#l44">4.3.4: retries - Specifying allowed failures</a></dt> -<dt><a href="#l45">4.3.5: weight - When a back end is more equal than others</a></dt> -<dt><a href="#l46">4.3.6: decay - Levelling out activity of a back end</a></dt> -<dt><a href="#l47">4.3.7: state - Setting an initial back end state</a></dt> -<dt><a href="#l48">4.3.8: onstart, onend, onfail - Action Hooks</a></dt> -<dt><a href="#l49">4.3.9: trafficlog and throughputlog - Debugging and Performance Aids</a></dt> -<dt><a href="#l50">4.3.10: stickycookie - Back end selection with an HTTP cookie</a></dt> -<dt><a href="#l51">4.3.11: HTTP Header Modification Directives</a></dt> +<dt><a href="#l42">4.4.1: server - Specifying the back end address</a></dt> +<dt><a href="#l43">4.4.2: port - Specifying a back end port</a></dt> +<dt><a href="#l44">4.4.3: verbosity - Controlling verbosity at the back end level</a></dt> +<dt><a href="#l45">4.4.4: retries - Specifying allowed failures</a></dt> +<dt><a href="#l46">4.4.5: maxconnections - Limiting the connections to a back end</a></dt> +<dt><a href="#l47">4.4.6: weight - When a back end is more equal than others</a></dt> +<dt><a href="#l48">4.4.7: decay - Levelling out activity of a back end</a></dt> +<dt><a href="#l49">4.4.8: state - Setting an initial back end state</a></dt> +<dt><a href="#l50">4.4.9: onstart, onend, onfail - Action Hooks</a></dt> +<dt><a href="#l51">4.4.10: trafficlog and throughputlog - Debugging and Performance Aids</a></dt> +<dt><a href="#l52">4.4.11: httptiminglog - Timing debugging in HTTP mode</a></dt> +<dt><a href="#l53">4.4.12: stickycookie - Back end selection with an HTTP cookie</a></dt> +<dt><a href="#l54">4.4.13: HTTP Header Modification Directives</a></dt> </dl> </dl> -<dt><h3><a href="#l52">5: Tips, Tricks and Random Remarks</a></h3></dt> +<dt><h3><a href="#l55">5: Tips, Tricks and Random Remarks</a></h3></dt> <dl> -<dt><a href="#l53">5.1: Configuration examples</a></dt> +<dt><a href="#l56">5.1: Configuration examples</a></dt> <dl> -<dt><a href="#l54">5.1.1: A load balancer for three webserver back ends</a></dt> -<dt><a href="#l55">5.1.2: An HTTP forwarder when travelling</a></dt> -<dt><a href="#l56">5.1.3: SSH login with enforced idle logout</a></dt> +<dt><a href="#l57">5.1.1: A load balancer for three webserver back ends</a></dt> +<dt><a href="#l58">5.1.2: An HTTP forwarder when travelling</a></dt> +<dt><a href="#l59">5.1.3: SSH login with enforced idle logout</a></dt> </dl> -<dt><a href="#l57">5.2: How back ends are selected in load balancing</a></dt> +<dt><a href="#l60">5.2: How back ends are selected in load balancing</a></dt> <dl> -<dt><a href="#l58">5.2.1: Bysize, byduration or byconnections?</a></dt> -<dt><a href="#l59">5.2.2: Averaging size and duration</a></dt> -<dt><a href="#l60">5.2.3: Specifying decays</a></dt> -<dt><a href="#l61">5.2.4: Adjusting the weights</a></dt> +<dt><a href="#l61">5.2.1: Bysize, byduration or byconnections?</a></dt> +<dt><a href="#l62">5.2.2: Averaging size and duration</a></dt> +<dt><a href="#l63">5.2.3: Specifying decays</a></dt> +<dt><a href="#l64">5.2.4: Adjusting the weights</a></dt> </dl> -<dt><a href="#l62">5.3: Periodic probes and wake up calls</a></dt> +<dt><a href="#l65">5.3: Periodic probes and wake up calls</a></dt> <dl> -<dt><a href="#l63">5.3.1: Syntax</a></dt> -<dt><a href="#l64">5.3.2: Security Considerations</a></dt> -<dt><a href="#l65">5.3.3: An example</a></dt> +<dt><a href="#l66">5.3.1: Syntax</a></dt> +<dt><a href="#l67">5.3.2: Security Considerations</a></dt> +<dt><a href="#l68">5.3.3: An example</a></dt> </dl> -<dt><a href="#l66">5.4: Throttling the number of concurrent connections</a></dt> -<dt><a href="#l67">5.5: TCP Session Stickiness</a></dt> -<dt><a href="#l68">5.6: HTTP Session Stickiness</a></dt> +<dt><a href="#l69">5.4: Throttling the number of concurrent connections</a></dt> +<dt><a href="#l70">5.5: TCP Session Stickiness</a></dt> +<dt><a href="#l71">5.6: HTTP Session Stickiness</a></dt> <dl> -<dt><a href="#l69">5.6.1: Don't use stickiness!</a></dt> -<dt><a href="#l70">5.6.2: But if you must..</a></dt> +<dt><a href="#l72">5.6.1: Don't use stickiness!</a></dt> +<dt><a href="#l73">5.6.2: But if you must..</a></dt> </dl> -<dt><a href="#l71">5.7: Passing the client's IP address</a></dt> +<dt><a href="#l74">5.7: Passing the client's IP address</a></dt> <dl> -<dt><a href="#l72">5.7.1: Sample Crossroads configuration</a></dt> -<dt><a href="#l73">5.7.2: Sample Apache configuration</a></dt> +<dt><a href="#l75">5.7.1: Sample Crossroads configuration</a></dt> +<dt><a href="#l76">5.7.2: Sample Apache configuration</a></dt> </dl> -<dt><a href="#l74">5.8: Deep or shallow HTTP header inspection</a></dt> -<dt><a href="#l75">5.9: Debugging network traffic</a></dt> -<dt><a href="#l76">5.10: IP filtering: Limiting Access by Client IP Address</a></dt> +<dt><a href="#l77">5.8: Deep or shallow HTTP header inspection</a></dt> +<dt><a href="#l78">5.9: Debugging network traffic</a></dt> +<dt><a href="#l79">5.10: IP filtering: Limiting Access by Client IP Address</a></dt> <dl> -<dt><a href="#l77">5.10.1: General Examples</a></dt> -<dt><a href="#l78">5.10.2: Using External Files</a></dt> -<dt><a href="#l79">5.10.3: Mixing Directives</a></dt> +<dt><a href="#l80">5.10.1: General Examples</a></dt> +<dt><a href="#l81">5.10.2: Using External Files</a></dt> +<dt><a href="#l82">5.10.3: Mixing Directives</a></dt> </dl> -<dt><a href="#l80">5.11: Using an external program to dispatch</a></dt> +<dt><a href="#l83">5.11: Using an external program to dispatch</a></dt> <dl> -<dt><a href="#l81">5.11.1: Configuring the external handler</a></dt> -<dt><a href="#l82">5.11.2: Writing the external handler</a></dt> -<dt><a href="#l83">5.11.3: Examples of external handlers</a></dt> +<dt><a href="#l84">5.11.1: Configuring the external handler</a></dt> +<dt><a href="#l85">5.11.2: Writing the external handler</a></dt> +<dt><a href="#l86">5.11.3: Examples of external handlers</a></dt> </dl> -<dt><a href="#l84">5.12: Linux and ip_conntrack_max</a></dt> -<dt><a href="#l85">5.13: Marking back ends as bad after more than one try</a></dt> -<dt><a href="#l86">5.14: Using the Web Interface crossroads-mgr</a></dt> +<dt><a href="#l87">5.12: Linux and ip_conntrack_max</a></dt> +<dt><a href="#l88">5.13: Marking back ends as bad after more than one try</a></dt> +<dt><a href="#l89">5.14: Using the Web Interface crossroads-mgr</a></dt> <dl> -<dt><a href="#l87">5.14.1: Starting crossroads-mgr</a></dt> +<dt><a href="#l90">5.14.1: Starting crossroads-mgr</a></dt> </dl> -<dt><a href="#l88">5.15: Rendering Crossroads' status in a web page</a></dt> -<dt><a href="#l89">5.16: Crossroads and DNS caching</a></dt> -<dt><a href="#l90">5.17: Managing a Pool of Virtual Back Ends</a></dt> +<dt><a href="#l91">5.15: Rendering Crossroads' status in a web page</a></dt> +<dt><a href="#l92">5.16: Crossroads and DNS caching</a></dt> +<dt><a href="#l93">5.17: Managing a Pool of Virtual Back Ends</a></dt> </dl> -<dt><h3><a href="#l91">6: Benchmarking</a></h3></dt> +<dt><h3><a href="#l94">6: Benchmarking</a></h3></dt> <dl> -<dt><a href="#l92">6.1: Benchmark 1: Accessing a proxy via crossroads or directly</a></dt> +<dt><a href="#l95">6.1: Benchmark 1: Accessing a proxy via crossroads or directly</a></dt> <dl> -<dt><a href="#l93">6.1.1: Results</a></dt> -<dt><a href="#l94">6.1.2: Discussion</a></dt> +<dt><a href="#l96">6.1.1: Results</a></dt> +<dt><a href="#l97">6.1.2: Discussion</a></dt> </dl> -<dt><a href="#l95">6.2: Benchmark 2: Crossroads versus Linux Virtual Server (LVS)</a></dt> +<dt><a href="#l98">6.2: Benchmark 2: Crossroads versus Linux Virtual Server (LVS)</a></dt> <dl> -<dt><a href="#l96">6.2.1: Environment</a></dt> -<dt><a href="#l97">6.2.2: Tests and results</a></dt> +<dt><a href="#l99">6.2.1: Environment</a></dt> +<dt><a href="#l100">6.2.2: Tests and results</a></dt> </dl> </dl> -<dt><h3><a href="#l98">7: Compiling and Installing</a></h3></dt> +<dt><h3><a href="#l101">7: Compiling and Installing</a></h3></dt> <dl> -<dt><a href="#l99">7.1: Prerequisites</a></dt> -<dt><a href="#l100">7.2: Compiling and installing</a></dt> -<dt><a href="#l101">7.3: Configuring crossroads</a></dt> -<dt><a href="#l102">7.4: A boot script</a></dt> +<dt><a href="#l102">7.1: Prerequisites</a></dt> +<dt><a href="#l103">7.2: Compiling and installing</a></dt> +<dt><a href="#l104">7.3: Configuring crossroads</a></dt> +<dt><a href="#l105">7.4: A boot script</a></dt> <dl> -<dt><a href="#l103">7.4.1: SysV Style Startup</a></dt> -<dt><a href="#l104">7.4.2: BSD Style Startup</a></dt> -<dt><a href="#l105">7.4.3: Linux-related</a></dt> +<dt><a href="#l106">7.4.1: SysV Style Startup</a></dt> +<dt><a href="#l107">7.4.2: BSD Style Startup</a></dt> +<dt><a href="#l108">7.4.3: Linux-related</a></dt> </dl> <p><hr><p> @@ -693,7 +696,7 @@ technical reasons for this. <p> However, external lists of allowed or denied IP addresses can be reloaded by sending a signal -1 (<code>SIGHUP</code>) to Crossroads. See -section <a href="crossroads.html#servicedef">4.2</a> for the details. +section <a href="crossroads.html#servicedef">4.3</a> for the details. <p> <a name="l20"></a> <h3>3.2: The Web Frontend: crossroads-mgr</h3> @@ -730,10 +733,28 @@ This section describes the general elements of the crossroads configuration language. <p> <a name="l23"></a> -<strong>4.1.1: Empty lines and comments</strong> +<strong>4.1.1: Empty lines, indentation and comments</strong> <p> -Empty lines are of course allowed in the -configuration. Crossroads recognizes three formats of comment: +Empty lines are of course allowed in the configuration. Also, +indentation is irrelevant as far as processing is concerned, but is +loosely inspired on a C-like style. So the following two examples are +identical as far as Crossroads is concerned (thought the first one +will be typically more readable): +<p> +<pre> +/* Example one */ +options { + tcpbuffersize 10240; + logactivity on; +} + +/* Example two */ +options {tcpbuffersize 10240 +;logactivity on;} +</pre> + +<p> +Crossroads recognizes the following comment formats: <p> <ul> <li> C-style, between <code>/*</code> and <code>*/</code>, @@ -835,6 +856,7 @@ grammar is: <code>backlog</code> <code>throughputlog</code> <code>trafficlog</code> +<code>httptiminglog</code> <code>stickycookie</code> <code>addclientheader</code> <code>setclientheader</code> @@ -856,6 +878,14 @@ grammar is: <code>available</code> <code>unavailable</code> <code>down</code> +<code>options</code> +<code>logactivity</code> +<code>tcpbuffersize</code> +<code>dnscachettl</code> +<code>logfacility</code> +<code>shmpermissions</code> +<code>sloppyportbind</code> +<code>leaveprocesstitle</code> <p> Many keywords require an <em>identifier</em> as the argument. E.g, a service has a unique name, which must start with a letter or @@ -865,7 +895,8 @@ digits. E.g., in the statement <code>service myservice</code>, the keyword is <p> Other keywords require a numeric argument. Crossroads knows only non-negative integer numbers, as in <code>port 8000</code>. Here, <code>port</code> is -the keyword and <code>8000</code> is the number. +the keyword and <code>8000</code> is the number. Octal numbers are specified by +prefixing a zero; e.g., <code>0644</code> is an octal number. <p> Yet other keywords require 'generic strings', such as hostname specifications or system commands. Such generic strings contain any @@ -887,7 +918,65 @@ Finally, an argument can be a 'boolean' value. Crossroads knows interchangeably; as can the keywords <code>false</code>, <code>no</code> and <code>off</code>. <p> <a name="l26"></a> -<h3>4.2: Service definitions</h3> <a name="servicedef"></a> +<h3>4.2: Daemon options</h3><a name="daemonoptions"></a> +<p> +Crossroads supports an optional block that defines run options for the +daemon process. These options can be also be specified on the command line +using flags. +<p> +The syntax of the options block is: +<p> +<pre> +options { + . + . option statements (see below) + . +} +</pre> + +<p> +In the curly-brace block the following option statements can occur: +<p> +<ul> + <li> <code>logactivity on;</code> or <code>off</code> Turns activity logging on + or off. This is also controlled using the flag <code>-a</code>. The + default is not to log network activity. +<p> +<li> <code>tcpbuffersize</code> <em>number</em> <code>;</code> This defines the size + of network buffers. The default is 5120 bytes. This is also + controlled using the flag <code>-B</code>. +<p> +<li> <code>dnscachettl</code> <em>number</em> <code>;</code> This controls the + time-to-live of cached DNS entries, in seconds. Value zero + means no caching and is the default. This is also controlled + using the flag <code>-d</code>. +<p> +<li> <code>logfacility</code> <em>number</em> <code>;</code> This controls the + logging facility. Values 0 to 7 select <code>LOG_LOCAL0</code> to + <code>LOG_LOCAL7</code>. Any other value selects <code>LOG_DAEMON</code>, which + is also the default. This is also controlled using the flag <code>-l</code>. +<p> +<li> <code>shmpermissions</code> <code>number</code> <code>;</code> This defines the + permissions (for user, group and other) of the shared memory + block. The number is most often specified as an octal value, + e.g. <code>0644</code>, which is also the default. This is also + controlled using the flag <code>-m</code>. +<p> +<li> <code>sloppyportbind on;</code> or <code>off</code> Turns on 'sloppy' port + binding of the listener. When <code>on</code>, Crossroads will not + treat port-busy conditions as fatal, but will wait and retry. + The default is <code>off</code>. This is also controlled using flag + <code>-s</code>. +<p> +<li> <code>leaveprocesstitle</code> <code>on;</code> or <code>off</code> When <code>on</code>, the + process title of Crossroads is not modified, so that <code>ps</code> + will show <code>crossroads-daemon</code>. The default is <code>off</code>: + Crosroads will modify its process name into something like + <em>crossroads - Sevice web: listening</em> or <em>crossroads - + Service web: serving</em>.</ul> +<p> +<a name="l27"></a> +<h3>4.3: Service definitions</h3> <a name="servicedef"></a> <p> Service definitions are blocks in the configuration file that state what is for each service. A service definition starts with @@ -910,8 +999,8 @@ 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/port"></a><a name="l27"></a> -<strong>4.2.1: port - Specifying the listen port</strong> <a name="confport - Specifying the listen port"></a> +<a name="conf/port"></a><a name="l28"></a> +<strong>4.3.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 @@ -924,8 +1013,8 @@ Multiple services in one configuration cannot use the same port <p><dt><strong>Default:</strong><dd> There is no default. This is a required setting. </dl> <p> -<a name="conf/type"></a><a name="l28"></a> -<strong>4.2.2: type - Defining the service type</strong> <a name="conftype - Defining the service type"></a> +<a name="conf/type"></a><a name="l29"></a> +<strong>4.3.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 @@ -944,8 +1033,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/headerinspection"></a><a name="l29"></a> -<strong>4.2.3: headerinspection - are all HTTP headers inspected</strong> <a name="confheaderinspection - are all HTTP headers inspected"></a> +<a name="conf/headerinspection"></a><a name="l30"></a> +<strong>4.3.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>headerinspection</code> directive defines whether Crossroads must inspect all HTTP headers that are seen on one TCP connection, or @@ -961,8 +1050,8 @@ that forms the server's answer, are analyzed. <p><dt><strong>Default:</strong><dd> <code>deep</code> </dl> <p> -<a name="conf/bindto"></a><a name="l30"></a> -<strong>4.2.4: 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="l31"></a> +<strong>4.3.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., @@ -975,8 +1064,8 @@ that forms the server's answer, are analyzed. <p><dt><strong>Default:</strong><dd> <code>any</code> </dl> <p> -<a name="conf/verbose"></a><a name="l31"></a> -<strong>4.2.5: verbosity - Controlling debug output</strong> <a name="confverbosity - Controlling debug output"></a> +<a name="conf/verbose"></a><a name="l32"></a> +<strong>4.3.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> @@ -992,8 +1081,8 @@ that forms the server's answer, are analyzed. <p><dt><strong>Default:</strong><dd> <code>off</code> </dl> <p> -<a name="conf/dispatchmode"></a><a name="l32"></a> -<strong>4.2.6: dispatchmode - How are back ends selected</strong> <a name="confdispatchmode - How are back ends selected"></a> +<a name="conf/dispatchmode"></a><a name="l33"></a> +<strong>4.3.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 @@ -1079,8 +1168,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="l33"></a> -<strong>4.2.7: revivinginterval - Back end wakeup calls</strong> <a name="confrevivinginterval - Back end wakeup calls"></a> +<a name="conf/revivinginterval"></a><a name="l34"></a> +<strong>4.3.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 used when Crossroads determines that a back end is temporarily unavailable. This will @@ -1109,8 +1198,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/checkinterval"></a><a name="l34"></a> -<strong>4.2.8: checkinterval - Periodic back end checks</strong> <a name="confcheckinterval - Periodic back end checks"></a> +<a name="conf/checkinterval"></a><a name="l35"></a> +<strong>4.3.8: checkinterval - Periodic back end checks</strong> <a name="confcheckinterval - Periodic back end checks"></a> <dl> <p><dt><strong>Description:</strong><dd> When a check interval is stated, Crossroads will periodically probe back ends to determine whether available back ends are @@ -1134,8 +1223,8 @@ The second form activates an external program (see section <p><dt><strong>Default:</strong><dd> 0 (no periodic checks) </dl> <p> -<a name="conf/maxconnections"></a><a name="l35"></a> -<strong>4.2.9: 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="l36"></a> +<strong>4.3.9: 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 @@ -1145,13 +1234,17 @@ The second form activates an external program (see section Service (DOS) attacks. Without a limit, numerous network connections may spawn so many server instances, that the service ultimately breaks down and becomes unavailable. +<p> +Note that <code>maxconnections</code> is also allowed in a backend + description block, in which case it limits the number of TCP + connections to that particular back end. <p><dt><strong>Syntax:</strong><dd> <code>maxconnections</code> <em>number</em>, where the number specifies the maximum of concurrent connections to the service. <p><dt><strong>Default:</strong><dd> 0, meaning that all connections will be accepted. </dl> <p> -<a name="conf/backlog"></a><a name="l36"></a> -<strong>4.2.10: backlog - The TCP Back Log size</strong> <a name="confbacklog - The TCP Back Log size"></a> +<a name="conf/backlog"></a><a name="l37"></a> +<strong>4.3.10: 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 @@ -1166,8 +1259,8 @@ The second form activates an external program (see section value for socket back log size. </dl> <p> -<a name="conf/shmkey"></a><a name="l37"></a> -<strong>4.2.11: shmkey - Shared Memory Access</strong> <a name="confshmkey - Shared Memory Access"></a> +<a name="conf/shmkey"></a><a name="l38"></a> +<strong>4.3.11: 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 @@ -1187,8 +1280,8 @@ The actual key value doesn't matter much, as long as it's unique own key, based on the service name. </dl> <p> -<a name="conf/allow"></a><a name="l38"></a> -<strong>4.2.12: allow* and deny* - Allowing or denying connections</strong> <a name="confallow* and deny* - Allowing or denying connections"></a> +<a name="conf/allow"></a><a name="l39"></a> +<strong>4.3.12: 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 @@ -1277,8 +1370,8 @@ allowfrom 192.168.1.24; <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="l39"></a> -<strong>4.2.13: 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="l40"></a> +<strong>4.3.13: 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 @@ -1295,8 +1388,8 @@ allowfrom 192.168.1.24; ID that was in effect when Crossroads was started. </dl> <p> -<a name="l40"></a> -<h3>4.3: Backend definitions</h3> +<a name="l41"></a> +<h3>4.4: Backend definitions</h3> <p> Inside the service definitions as are described in the previous section, <em>backend definitions</em> must also occur. Backend definitions @@ -1331,8 +1424,8 @@ 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="l41"></a> -<strong>4.3.1: server - Specifying the back end address</strong> <a name="confserver - Specifying the back end address"></a> +<a name="conf/server.yo"></a><a name="l42"></a> +<strong>4.4.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 (server name) where it is located. For example: <code>server @@ -1349,8 +1442,8 @@ 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/backendport.yo"></a><a name="l42"></a> -<strong>4.3.2: port - Specifying a back end port</strong> <a name="confport - Specifying a back end port"></a> +<a name="conf/backendport.yo"></a><a name="l43"></a> +<strong>4.4.2: port - Specifying a back end port</strong> <a name="confport - Specifying a back end port"></a> <dl> <p><dt><strong>Description:</strong><dd> Back ends must be known by their host name and a port. Both can be simultaneously specified in a <code>server</code> statement. When the @@ -1361,8 +1454,8 @@ i.e., when the service is declared with <code>type http</code>. Incase of using <code>server</code> or using <code>port</code>. </dl> <p> -<a name="conf/verbose-backend.yo"></a><a name="l43"></a> -<strong>4.3.3: verbosity - Controlling verbosity at the back end level</strong> <a name="confverbosity - Controlling verbosity at the back end level"></a> +<a name="conf/verbose-backend.yo"></a><a name="l44"></a> +<strong>4.4.3: 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 <code>backend</code> can have its own verbosity (<code>on</code> or <code>off</code>). When @@ -1375,8 +1468,8 @@ 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="l44"></a> -<strong>4.3.4: retries - Specifying allowed failures</strong> <a name="confretries - Specifying allowed failures"></a> +<a name="conf/retries.yo"></a><a name="l45"></a> +<strong>4.4.4: 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 marked as unavailable after not just one failure, but after @@ -1390,8 +1483,21 @@ i.e., when the service is declared with <code>type http</code>. Incase of connection. </dl> <p> -<a name="conf/weight"></a><a name="l45"></a> -<strong>4.3.5: weight - When a back end is more equal than others</strong> <a name="confweight - When a back end is more equal than others"></a> +<a name="conf/maxcon-client.yo"></a><a name="l46"></a> +<strong>4.4.5: maxconnections - Limiting the connections to a back end</strong> <a name="confmaxconnections - Limiting the connections to a back end"></a> + <dl> + <p><dt><strong>Description:</strong><dd> The directive <code>maxconnections</code> can also occur on the level of + back ends. In this case it limits the number of allowed + connections to this client. +<p> +Note that this directive can also occur on the level of a service + block, in which case it limits the overall number of connections. + <p><dt><strong>Syntax:</strong><dd> <code>maxconnections</code> <em>number</em> <code>;</code> + <p><dt><strong>Default:</strong><dd> 0; meaning no limit + </dl> +<p> +<a name="conf/weight"></a><a name="l47"></a> +<strong>4.4.6: 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 'weight' in the process. The higher the weight, the less likely a @@ -1409,8 +1515,8 @@ 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="l46"></a> -<strong>4.3.6: decay - Levelling out activity of a back end</strong> <a name="confdecay - Levelling out activity of a back end"></a> +<a name="conf/decay"></a><a name="l48"></a> +<strong>4.4.7: 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 influence the perceived load of a back end forever, you may @@ -1431,8 +1537,8 @@ 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/state"></a><a name="l47"></a> -<strong>4.3.7: state - Setting an initial back end state</strong> <a name="confstate - Setting an initial back end state"></a> +<a name="conf/state"></a><a name="l49"></a> +<strong>4.4.8: state - Setting an initial back end state</strong> <a name="confstate - Setting an initial back end state"></a> <dl> <p><dt><strong>Description:</strong><dd> Using the <code>state</code> directive a back end can be 'primed' with an initial state. The keyword <code>state</code> can be followed by @@ -1448,8 +1554,8 @@ This means that when a given back end is hit, then its usage data initial dispatching. </dl> <p> -<a name="conf/onhooks"></a><a name="l48"></a> -<strong>4.3.8: onstart, onend, onfail - Action Hooks</strong> <a name="confonstart, onend, onfail - Action Hooks"></a> +<a name="conf/onhooks"></a><a name="l50"></a> +<strong>4.4.9: 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 specified to start system commands (external programs) when a @@ -1528,8 +1634,8 @@ 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="l49"></a> -<strong>4.3.9: trafficlog and throughputlog - Debugging and Performance Aids</strong> <a name="conftrafficlog and throughputlog - Debugging and Performance Aids"></a> +<a name="conf/trafficlog"></a><a name="l51"></a> +<strong>4.4.10: 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 to log network traffic to files. They are <code>trafficlog</code> and @@ -1541,15 +1647,34 @@ The <code>trafficlog</code> statement causes all traffic to be logged in end or from the client. <p> The <code>throughputlog</code> statement writes shorthand transmissions to - its log, accompanied by timings. - <p><dt><strong>Syntax:</strong><dd> <ul> - <li> <code>trafficlog</code> <em>filename</em> - <li> <code>throughputlog</code> <em>filename</em></ul> + its log, accompanied by timings and the number of bytes each + transmission was able to read or write in one chunk. + <p><dt><strong>Syntax:</strong><dd> The syntax is: +<p> +<ul> + <li> <code>trafficlog</code> <em>filename</em> <code>;</code> + <li> <code>throughputlog</code> <em>filename</em> <code>;</code></ul> + <p><dt><strong>Default:</strong><dd> none + </dl> +<p> +<a name="conf/httptiminglog"></a><a name="l52"></a> +<strong>4.4.11: httptiminglog - Timing debugging in HTTP mode</strong> <a name="confhttptiminglog - Timing debugging in HTTP mode"></a> + <dl> + <p><dt><strong>Description:</strong><dd> The directive <code>httptiminglog</code> turns on logging of HTTP mode + timing. There must be one argument, the filename where the timings + are written to. Turning on this option will slow down processing, + but may be helpful in finding out where delays are caused. + <p><dt><strong>Syntax:</strong><dd> The syntax is: +<p> +<ul> + <li> <code>httptiminglog</code> <em>filename</em> <code>;</code> + <li> Where <em>filename</em> is the output file, e.g. + <code>/tmp/timings.log</code></ul> <p><dt><strong>Default:</strong><dd> none </dl> <p> -<a name="conf/stickycookie"></a><a name="l50"></a> -<strong>4.3.10: stickycookie - Back end selection with an HTTP cookie</strong> <a name="confstickycookie - Back end selection with an HTTP cookie"></a> +<a name="conf/stickycookie"></a><a name="l53"></a> +<strong>4.4.12: 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> causes Crossroads to unpack clients' requests, to check for @@ -1588,8 +1713,8 @@ 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="l51"></a> -<strong>4.3.11: HTTP Header Modification Directives</strong> <a name="confHTTP Header Modification Directives"></a> +<a name="conf/addclientheader"></a><a name="l54"></a> +<strong>4.4.13: HTTP Header Modification Directives</strong> <a name="confHTTP Header Modification Directives"></a> <dl> <p><dt><strong>Description:</strong><dd> Crossroads understands the following header modification directives: <code>addclientheader</code>, @@ -1801,16 +1926,16 @@ service ... { <p><dt><strong>Default:</strong><dd> There is no default. </dl> <p> -<a name="l52"></a> +<a name="l55"></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="l53"></a> +<a name="l56"></a> <h3>5.1: Configuration examples</h3> <a name="tips/examples"></a> -<a name="l54"></a> +<a name="l57"></a> <strong>5.1.1: A load balancer for three webserver back ends</strong> <p> The following configuration example binds crossroads to port 80 of the @@ -1939,7 +2064,7 @@ service www { </pre> <p> -<a name="l55"></a> +<a name="l58"></a> <strong>5.1.2: An HTTP forwarder when travelling</strong> <p> As another example, here's my /etc/crossroads.conf that I use on my @@ -2028,7 +2153,7 @@ and <code>LocalSquid</code> are both active, then <code>crossroads tell httpprox 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="l56"></a> +<a name="l59"></a> <strong>5.1.3: SSH login with enforced idle logout</strong> <p> The following example shows how crossroads 'throttles' SSH @@ -2054,7 +2179,7 @@ service Ssh { </pre> <p> -<a name="l57"></a> +<a name="l60"></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 @@ -2062,7 +2187,7 @@ section we'll focus on the dispatching modes <code>bysize</code>, <code>bydurati and <code>byconnections</code> only. The other dispatching types are self-explanatory. <p> -<a name="l58"></a> +<a name="l61"></a> <strong>5.2.1: Bysize, byduration or byconnections?</strong> <p> As stated before, crossroads doesn't know 'what a service does' and @@ -2112,7 +2237,7 @@ E.g., consider a database connection. What's <p> </ul> <p> -<a name="l59"></a> +<a name="l62"></a> <strong>5.2.2: Averaging size and duration</strong> <p> The configuration statement <code>dispatchmode bysize</code> or <code>byduration</code> @@ -2133,7 +2258,7 @@ 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="l60"></a> +<a name="l63"></a> <strong>5.2.3: Specifying decays</strong> <p> Decays are also only relevant when crossroads computes the 'next best @@ -2187,7 +2312,7 @@ service soap { </pre> <p> -<a name="l61"></a> +<a name="l64"></a> <strong>5.2.4: Adjusting the weights</strong> <p> The back end modifier <code>weight</code> is useful in situations where your @@ -2241,7 +2366,7 @@ 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="l62"></a> +<a name="l65"></a> <h3>5.3: Periodic probes and wake up calls</h3> <a name="tips/periodic"></a>Crossroads has two methods of periodic back end verifications: <p> @@ -2265,7 +2390,7 @@ than its smaller siblings. <code>checkinterval</code>. During each check, back ends can be marked as available or as unavailable.</ul> <p> -<a name="l63"></a> +<a name="l66"></a> <strong>5.3.1: Syntax</strong> <p> The syntax of both verifications is: @@ -2337,7 +2462,7 @@ The <em>arguments</em> are expanded according to the following table: <li> Any other chararacter following a <code>%</code> sign is taken literally; e.g. <code>%z</code> is just a z.</ul> <p> -<a name="l64"></a> +<a name="l67"></a> <strong>5.3.2: Security Considerations</strong> <p> When <code>externalhandler</code> is in effect, Crossroads spawns an external @@ -2346,7 +2471,7 @@ a restricted user account. <p> The directive <code>useraccount</code> can be used to accomplish this. <p> -<a name="l65"></a> +<a name="l68"></a> <strong>5.3.3: An example</strong> <p> The following configuration balances SMTP requests to two back @@ -2383,7 +2508,7 @@ service smtp { </pre> <p> -<a name="l66"></a> +<a name="l69"></a> <h3>5.4: Throttling the number of concurrent connections</h3> <a name="tips/throttling"></a>If you suspect that your service may occasionally receive 'spikes' of activity (which you should always assume), then it might be a @@ -2412,7 +2537,7 @@ 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="l67"></a> +<a name="l70"></a> <h3>5.5: 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 @@ -2437,7 +2562,7 @@ 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="l68"></a> +<a name="l71"></a> <h3>5.6: 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 @@ -2445,7 +2570,7 @@ 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="l69"></a> +<a name="l72"></a> <strong>5.6.1: Don't use stickiness!</strong> <p> The rule of thumb as far as the balancer is concerned, is: <strong>Do not @@ -2477,7 +2602,7 @@ 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="l70"></a> +<a name="l73"></a> <strong>5.6.2: But if you must..</strong> <p> If you really need stickiness, think first whether you might use TCP @@ -2562,7 +2687,7 @@ 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="l71"></a> +<a name="l74"></a> <h3>5.7: 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, @@ -2592,7 +2717,7 @@ header: <code>X-Real-IP</code>, holding the client's IP address. performance will be hampered -- all passing messages will have to be unpacked and analyzed. <p> -<a name="l72"></a> +<a name="l75"></a> <strong>5.7.1: Sample Crossroads configuration</strong> <p> The below sample configuration shows two HTTP back ends that receive @@ -2619,7 +2744,7 @@ service www { </pre> <p> -<a name="l73"></a> +<a name="l76"></a> <strong>5.7.2: Sample Apache configuration</strong> <p> The method by which each back end analyzes the header <code>X-Real-IP</code> @@ -2651,7 +2776,7 @@ LogFormat "%{X-Real-IP}i %l %u %t %D \"%r\" %>s %b" common </pre> <p> -<a name="l74"></a> +<a name="l77"></a> <h3>5.8: 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 @@ -2763,13 +2888,12 @@ In these examples, <code>shallow</code> mode is not usable, because the HTTP server signature. All subsequent transactions would still show the HTTP server signature to the world.</ul> <p> -<a name="l75"></a> +<a name="l78"></a> <h3>5.9: 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 - be issued. This causes the traffic to be dumped in hexadecimal - format to the stated filename. +<a name="tips/debugging"></a> Incase the traffic between client and backend must be debugged, + the statement <code>trafficlog</code> <em>filename</em> can be issued. This + causes the traffic to be dumped in hexadecimal format to the + stated filename. <p> Traffic sent by the client is prefixed by a <strong>C</strong>, traffic sent by the back end is prefixed by a <strong>B</strong>. Below is a sample traffic @@ -2798,8 +2922,8 @@ B 0050 78 74 2f 68 74 6d 6c 3b 20 63 68 61 72 73 65 74 xt/html; charset </pre> <p> -Turning on traffic dumps will <em>significantly</em> - slow down crossroads. +Turning on traffic dumps will <em>significantly</em> slow down + crossroads. <p> Besides <code>trafficlog</code>, there is also a directive <code>throughputlog</code>. This directive also takes one argument, a @@ -2820,39 +2944,35 @@ As an example, consider the following (the lines are shortened for <p> <pre> -1 0000594 0.000001 C GET http://public.e-tunity.com/index.html... -2 0000594 0.173713 B HTTP/1.0 200 OK..Date: Fri, 18 Nov 2005 0... -3 0000594 0.278125 B width="100" bgcolor="#e0e0e0" valign="to... -4 0000595 0.000001 C GET http://public.e-tunity.com/css/style/... -5 0000594 0.944339 B /a></td>.. </tr>.</table>.</td><td class... -6 0000594 0.946356 B smallboxdownl">Download</td>.. <td class... -7 0000594 0.961102 B td><td class="smallboxodd" valign="top"><... -8 0000595 0.698215 B HTTP/1.0 304 Not Modified..Date: Fri, 18 ... +1 0027566 0.000000 C 462 GET http://public.e-tunity.com/ ... +2 0027566 0.052974 B 394 HTTP/1.1 200 OK..Via: 1.1 tinyp ... +3 0027566 0.053413 B 1073 <html>.. <head>.. <titl ... +4 0027566 0.053589 B 1448 1> </td>.. </tr>.. </table ... +5 0027566 0.065679 B 725 for more. info.... <li> To ... </pre> <p> This tells us that: <p> <ul> - <li> Line 1: PID 594 served a request that originated at - the client. The corresponding time is (almost) 0 seconds, - so this is really the start of the run. - <li> Line 2: A back end replied 0.17 seconds later, and - 0.28 seconds later, it was still replying (this is the - third line, again a <strong>B</strong>-type transmission). - <li> Line 4: PID 595 served a request that originated - at the client. Again, the corresponding time is (almost) - 0 seconds, since this is the first conversation part of - this connection. - <li> Lines 5 to 7: This is the continuation of line 2. Line 7 - is the last line of the <strong>B</strong> series (not visible from - the example, but trust me, it is), so that we may - conclude that it took the back end 0.96 seconds to serve - the file <code>index.html</code> requested in line 1. - <li> Line 8: This is the answer to the client's request of - line 4 (you can tell by the process ID number). - So the back end took 0.68 seconds to confirm that - the stylesheet requested in line 4 wasn't modified.</ul> + <li> Line 1: PID 27566 served a request that originated at the + client (C). The corresponding timing is 0 seconds, which means + that this is the start of the run. The request was 462 bytes + long and started with <code>GET http://public...</code> +<p> +<li> Line 2: 0.052974 seconds later, the backend (B) replied + with <code>HTTP/1.1 200 OK</code>. +<p> +<li> Lines 3, 4 and 5: The backend (B) proceeded by sending + chunks.</ul> +<p> +The buffer sizes (462, 394 and so on) also tell us that the + network sends relatively small chunks. In this case we might save + some processing memory by setting the TCP buffer size to say 2K, + instead of the default 5K. In this situation, most of the default + 5K buffers will be unused. Setting the TCP buffer size to 2K can be done + using the flag <code>-B 2048</code> or by using the statement + <code>tcpbuffersize</code> <code>2048;</code> in an <code>options</code> block of the configuration. <p> It is also worth while remembering that the start time of a <strong>C</strong> request is the time that crossroads sees the activity. Any latency @@ -2870,7 +2990,7 @@ client ----<----<----<---< crossroads ====<====<====< </pre> <p> -This simple picture shows a typical HTTP request that originates +This simple picture shows a typical request that originates at a client, travels to crossroads, and is relayed via the back end. The <strong>C</strong> entry in a throughput log is the time when crossroads sees the request, indicated by an asterisk. The <strong>B</strong> @@ -2880,15 +3000,15 @@ This simple picture shows a typical HTTP request that originates the throughput log: the latency between client and crossroads isn't included in that measurement. <p> -Summarizing, the throughput times of a client-back end connection - can be analyzed using the directive <code>throughputlog</code>. In a - real-world analysis, you'd probably want to write up a script to - analyze the output and to compute round trip times. Such scripts - are not (yet) included in Crossroads. +Summarizing, the throughput times and buffer sizes of a + client-back end connection can be analyzed using the directive + <code>throughputlog</code>. In a real-world analysis, you'd probably want + to write up a script to analyze the output and to compute round + trip times. Such scripts are not (yet) included in Crossroads. <p> -<a name="l76"></a> +<a name="l79"></a> <h3>5.10: IP filtering: Limiting Access by Client IP Address</h3> -<a name="tips/ipfiltering"></a><a name="l77"></a> +<a name="tips/ipfiltering"></a><a name="l80"></a> <strong>5.10.1: General Examples</strong> <p> The directives <code>allowfrom</code>, <code>denyfrom</code>, <code>allowfile</code> and @@ -2925,7 +3045,7 @@ 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="l78"></a> +<a name="l81"></a> <strong>5.10.2: Using External Files</strong> <p> The directives <code>allowfile</code> and <code>denyfile</code> allow you to specify IP @@ -2957,7 +3077,7 @@ 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="l79"></a> +<a name="l82"></a> <strong>5.10.3: Mixing Directives</strong> <p> Crossroads allows to mix all directives in one service @@ -3024,14 +3144,14 @@ 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="l80"></a> +<a name="l83"></a> <h3>5.11: 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="l81"></a> +<a name="l84"></a> <strong>5.11.1: Configuring the external handler</strong> <p> First, the <code>dispatchmode</code> statement needs to inform Crossroads that @@ -3097,7 +3217,7 @@ 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="l82"></a> +<a name="l85"></a> <strong>5.11.2: Writing the external handler</strong> <p> The external handler is activated using the arguments that are @@ -3106,7 +3226,7 @@ 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="l83"></a> +<a name="l86"></a> <strong>5.11.3: Examples of external handlers</strong> <p> This section shows some examples of Crossroads configurations @@ -3533,7 +3653,7 @@ if ($action eq 'dispatch') { </pre> <p> -<a name="l84"></a> +<a name="l87"></a> <h3>5.12: 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 @@ -3569,7 +3689,7 @@ 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="l85"></a> +<a name="l88"></a> <h3>5.13: 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 @@ -3614,7 +3734,7 @@ 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="l86"></a> +<a name="l89"></a> <h3>5.14: Using the Web Interface crossroads-mgr</h3> <a name="tips/webinterface"></a>The mini-webserver <code>crossroads-mgr</code> provides an intuitive web interface to the state of Crossroads. Once started, an administrator @@ -3665,7 +3785,7 @@ The web interface doesn't offer extra functionality over the command line tools; but all information is available at one glance, and accessible without a shell access to the balancer. <p> -<a name="l87"></a> +<a name="l90"></a> <strong>5.14.1: Starting crossroads-mgr</strong> <p> The basic command to start <code>crossroads-mgr</code> is @@ -3739,7 +3859,7 @@ echo -e 'viewer:showme\nmodifier:changeit' | </pre> <p> -<a name="l88"></a> +<a name="l91"></a> <h3>5.15: Rendering Crossroads' status in a web page</h3> <a name="xmlstatus"></a> <a name="tips/rendering"></a>The Crossroads flag <code>-x</code> causes the status output to be generated as an XML document. This format can be nicely used to render the output @@ -3810,7 +3930,7 @@ 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="l89"></a> +<a name="l92"></a> <h3>5.16: Crossroads and DNS caching</h3> <a name="tips/dnscaching"></a> The option <code>-d</code> allows you to control Crossroads' built in DNS @@ -3834,7 +3954,7 @@ 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="l90"></a> +<a name="l93"></a> <h3>5.17: Managing a Pool of Virtual Back Ends</h3> <a name="tips/virtual"></a>Crossroads can be used as a central dispatcher for computing on demand. E.g., imagine a situation where a web service exists on one or @@ -3919,13 +4039,13 @@ end or to remove one, is left to the reader. The output of states of all back ends, their connections, the total number of available or down back ends, etc.. <p> -<a name="l91"></a> +<a name="l94"></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="l92"></a> +<a name="l95"></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: @@ -3953,7 +4073,7 @@ service HttpProxy { </pre> <p> -<a name="l93"></a> +<a name="l96"></a> <strong>6.1.1: Results</strong> <p> The results of this test are that crossroads causes a negligible @@ -3976,7 +4096,7 @@ sys 0m0.230s </pre> <p> -<a name="l94"></a> +<a name="l97"></a> <strong>6.1.2: Discussion</strong> <p> The above shown results are quite favorable to crossroads. However, @@ -4008,7 +4128,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="l95"></a> +<a name="l98"></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 @@ -4022,7 +4142,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="l96"></a> +<a name="l99"></a> <strong>6.2.1: Environment</strong> <p> On the balancer, LVS was run on port 80, its forwarding set up for two @@ -4053,7 +4173,7 @@ service http { </pre> <p> -<a name="l97"></a> +<a name="l100"></a> <strong>6.2.2: Tests and results</strong> <p> In the first test, ports 80 and 81 on the balancer were 'bombed' with @@ -4132,9 +4252,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="l98"></a> +<a name="l101"></a> <h2>7: Compiling and Installing</h2> <a name="installation"></a> -<a name="compiling"></a><a name="l99"></a> +<a name="compiling"></a><a name="l102"></a> <h3>7.1: Prerequisites</h3> <p> The creation of crossroads requires: @@ -4153,7 +4273,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="l100"></a> +<a name="l103"></a> <h3>7.2: Compiling and installing</h3> <p> <ul> @@ -4217,7 +4337,7 @@ crossroads, follow these steps. <p> </ul> <p> -<a name="l101"></a> +<a name="l104"></a> <h3>7.3: Configuring crossroads</h3> <p> Now that the binary is available on your system, you need to create a @@ -4265,13 +4385,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="l102"></a> +<a name="l105"></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="l103"></a> +<a name="l106"></a> <strong>7.4.1: SysV Style Startup</strong> <p> On SysV style systems, there's a startup script directory @@ -4325,7 +4445,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="l104"></a> +<a name="l107"></a> <strong>7.4.2: BSD Style Startup</strong> <p> On BSD style systems, daemons are booted directly from <code>/etc/rc</code> and @@ -4341,7 +4461,7 @@ and add the statement: If your BSD system lacks <code>/etc/rc.local</code>, then you may need to start Crossroads from <code>/etc/rc</code>. Your mileage may vary. <p> -<a name="l105"></a> +<a name="l108"></a> <strong>7.4.3: Linux-related</strong> <p> When using Crossroads on Linux, the following may be relevant: diff --git a/doc/crossroads.pdf b/doc/crossroads.pdf Binary files differ. diff --git a/doc/main/conf/httptiminglog.yo b/doc/main/conf/httptiminglog.yo @@ -0,0 +1,12 @@ +conf(httptiminglog - Timing debugging in HTTP mode) + (The directive tt(httptiminglog) turns on logging of HTTP mode + timing. There must be one argument, the filename where the timings + are written to. Turning on this option will slow down processing, + but may be helpful in finding out where delays are caused.) + (The syntax is: + + itemization( + it() tt(httptiminglog) em(filename) tt(;) + it() Where em(filename) is the output file, e.g. + tt(/tmp/timings.log))) + (none) diff --git a/doc/main/conf/maxcon-client.yo b/doc/main/conf/maxcon-client.yo @@ -0,0 +1,11 @@ +conf(maxconnections - Limiting the connections to a back end) + (The directive tt(maxconnections) can also occur on the level of + back ends. In this case it limits the number of allowed + connections to this client. + + Note that this directive can also occur on the level of a service + block, in which case it limits the overall number of connections.) + (tt(maxconnections) em(number) tt(;)) + (0; meaning no limit) + + +\ No newline at end of file diff --git a/doc/main/conf/maxconnections.yo b/doc/main/conf/maxconnections.yo @@ -6,7 +6,11 @@ conf(maxconnections - Limiting concurrent clients at service level) 'Throttling' the number of connections is a way of preventing Denial of Service (DOS) attacks. Without a limit, numerous network connections may spawn so many server instances, that the service ultimately breaks - down and becomes unavailable.) + down and becomes unavailable. + + Note that tt(maxconnections) is also allowed in a backend + description block, in which case it limits the number of TCP + connections to that particular back end.) (tt(maxconnections) em(number), where the number specifies the maximum of concurrent connections to the service.) (0, meaning that all connections will be accepted.) diff --git a/doc/main/conf/trafficlog.yo b/doc/main/conf/trafficlog.yo @@ -9,9 +9,12 @@ conf(trafficlog and throughputlog - Debugging and Performance Aids) end or from the client. The tt(throughputlog) statement writes shorthand transmissions to - its log, accompanied by timings.) - (itemization( - it() tt(trafficlog) em(filename) - it() tt(throughputlog) em(filename))) + its log, accompanied by timings and the number of bytes each + transmission was able to read or write in one chunk.) + (The syntax is: + + itemization( + it() tt(trafficlog) em(filename) tt(;) + it() tt(throughputlog) em(filename) tt(;))) (none) diff --git a/doc/main/config.yo b/doc/main/config.yo @@ -11,10 +11,25 @@ This section describes the general elements of the crossroads configuration language. -confsubsect(Empty lines and comments) +confsubsect(Empty lines, indentation and comments) -Empty lines are of course allowed in the -configuration. Crossroads recognizes three formats of comment: +Empty lines are of course allowed in the configuration. Also, +indentation is irrelevant as far as processing is concerned, but is +loosely inspired on a C-like style. So the following two examples are +identical as far as Crossroads is concerned (thought the first one +will be typically more readable): + +verb(/* Example one */ +options { + tcpbuffersize 10240; + logactivity on; +} + +/* Example two */ +options {tcpbuffersize 10240 +;logactivity on;}) + +Crossroads recognizes the following comment formats: itemization( it() C-style, between tt(/*) and tt(*/), @@ -26,6 +41,7 @@ best'.footnote(I favor C or C++ comment. My favorite editor em(emacs) can be put in tt(cmode) and nicely highlight what's comment and what's not. And as a bonus it will auto-indent the configuration!) + confsubsect(Preprocessor directives) Similar to bf(C) or bf(C++), the Crossroads grammar knows tt(#include) @@ -88,7 +104,8 @@ tt(service) and the identifier is tt(myservice). Other keywords require a numeric argument. Crossroads knows only non-negative integer numbers, as in tt(port 8000). Here, tt(port) is -the keyword and tt(8000) is the number. +the keyword and tt(8000) is the number. Octal numbers are specified by +prefixing a zero; e.g., tt(0644) is an octal number. Yet other keywords require 'generic strings', such as hostname specifications or system commands. Such generic strings contain any @@ -110,6 +127,61 @@ tt(true), tt(yes) and tt(on) all mean the same and can be used interchangeably; as can the keywords tt(false), tt(no) and tt(off). +confsect(Daemon options)label(daemonoptions) + +Crossroads supports an optional block that defines run options for the +daemon process. These options can be also be specified on the command line +using flags. + +The syntax of the options block is: + +verb(options { + . + . option statements (see below) + . +}) + +In the curly-brace block the following option statements can occur: + +itemization( + it() tt(logactivity on;) or tt(off) Turns activity logging on + or off. This is also controlled using the flag tt(-a). The + default is not to log network activity. + + it() tt(tcpbuffersize) em(number) tt(;) This defines the size + of network buffers. The default is 5120 bytes. This is also + controlled using the flag tt(-B). + + it() tt(dnscachettl) em(number) tt(;) This controls the + time-to-live of cached DNS entries, in seconds. Value zero + means no caching and is the default. This is also controlled + using the flag tt(-d). + + it() tt(logfacility) em(number) tt(;) This controls the + logging facility. Values 0 to 7 select tt(LOG_LOCAL0) to + tt(LOG_LOCAL7). Any other value selects tt(LOG_DAEMON), which + is also the default. This is also controlled using the flag tt(-l). + + it() tt(shmpermissions) tt(number) tt(;) This defines the + permissions (for user, group and other) of the shared memory + block. The number is most often specified as an octal value, + e.g. tt(0644), which is also the default. This is also + controlled using the flag tt(-m). + + it() tt(sloppyportbind on;) or tt(off) Turns on 'sloppy' port + binding of the listener. When tt(on), Crossroads will not + treat port-busy conditions as fatal, but will wait and retry. + The default is tt(off). This is also controlled using flag + tt(-s). + + it() tt(leaveprocesstitle) tt(on;) or tt(off) When tt(on), the + process title of Crossroads is not modified, so that tt(ps) + will show tt(crossroads-daemon). The default is tt(off): + Crosroads will modify its process name into something like + em(crossroads - Sevice web: listening) or em(crossroads - + Service web: serving).) + + confsect(Service definitions) label(servicedef) Service definitions are blocks in the configuration file that @@ -192,10 +264,12 @@ includefile(conf/server.yo) includefile(conf/backendport.yo) includefile(conf/verbose-backend.yo) includefile(conf/retries.yo) +includefile(conf/maxcon-client.yo) includefile(conf/weight) includefile(conf/decay) includefile(conf/state) includefile(conf/onhooks) includefile(conf/trafficlog) +includefile(conf/httptiminglog) includefile(conf/stickycookie) includefile(conf/addclientheader) diff --git a/doc/main/keywords.yo b/doc/main/keywords.yo @@ -31,6 +31,7 @@ tt(onfail) tt(backlog) tt(throughputlog) tt(trafficlog) +tt(httptiminglog) tt(stickycookie) tt(addclientheader) tt(setclientheader) @@ -52,3 +53,11 @@ tt(state) tt(available) tt(unavailable) tt(down) +tt(options) +tt(logactivity) +tt(tcpbuffersize) +tt(dnscachettl) +tt(logfacility) +tt(shmpermissions) +tt(sloppyportbind) +tt(leaveprocesstitle) diff --git a/doc/main/tips/debugging.yo b/doc/main/tips/debugging.yo @@ -1,8 +1,7 @@ - Incase the traffic between - client and backend - must be debugged, the statement tt(trafficlog) em(filename) can - be issued. This causes the traffic to be dumped in hexadecimal - format to the stated filename. + Incase the traffic between client and backend must be debugged, + the statement tt(trafficlog) em(filename) can be issued. This + causes the traffic to be dumped in hexadecimal format to the + stated filename. Traffic sent by the client is prefixed by a bf(C), traffic sent by the back end is prefixed by a bf(B). Below is a sample traffic @@ -29,8 +28,8 @@ B 0050 78 74 2f 68 74 6d 6c 3b 20 63 68 61 72 73 65 74 xt/html; charset . etcetera .) - Turning on traffic dumps will em(significantly) - slow down crossroads. + Turning on traffic dumps will em(significantly) slow down + crossroads. Besides tt(trafficlog), there is also a directive tt(throughputlog). This directive also takes one argument, a @@ -50,38 +49,34 @@ B 0050 78 74 2f 68 74 6d 6c 3b 20 63 68 61 72 73 65 74 xt/html; charset brevity and prefixed by line numbers for clarity): verb( -1 0000594 0.000001 C GET http://public.e-tunity.com/index.html... -2 0000594 0.173713 B HTTP/1.0 200 OK..Date: Fri, 18 Nov 2005 0... -3 0000594 0.278125 B width="100" bgcolor="#e0e0e0" valign="to... -4 0000595 0.000001 C GET http://public.e-tunity.com/css/style/... -5 0000594 0.944339 B /a></td>.. </tr>.</table>.</td><td class... -6 0000594 0.946356 B smallboxdownl">Download</td>.. <td class... -7 0000594 0.961102 B td><td class="smallboxodd" valign="top"><... -8 0000595 0.698215 B HTTP/1.0 304 Not Modified..Date: Fri, 18 ...) +1 0027566 0.000000 C 462 GET http://public.e-tunity.com/ ... +2 0027566 0.052974 B 394 HTTP/1.1 200 OK..Via: 1.1 tinyp ... +3 0027566 0.053413 B 1073 <html>.. <head>.. <titl ... +4 0027566 0.053589 B 1448 1> </td>.. </tr>.. </table ... +5 0027566 0.065679 B 725 for more. info.... <li> To ...) This tells us that: itemization( - it() Line 1: PID 594 served a request that originated at - the client. The corresponding time is (almost) 0 seconds, - so this is really the start of the run. - it() Line 2: A back end replied 0.17 seconds later, and - 0.28 seconds later, it was still replying (this is the - third line, again a bf(B)-type transmission). - it() Line 4: PID 595 served a request that originated - at the client. Again, the corresponding time is (almost) - 0 seconds, since this is the first conversation part of - this connection. - it() Lines 5 to 7: This is the continuation of line 2. Line 7 - is the last line of the bf(B) series (not visible from - the example, but trust me, it is), so that we may - conclude that it took the back end 0.96 seconds to serve - the file tt(index.html) requested in line 1. - it() Line 8: This is the answer to the client's request of - line 4 (you can tell by the process ID number). - So the back end took 0.68 seconds to confirm that - the stylesheet requested in line 4 wasn't modified.) + it() Line 1: PID 27566 served a request that originated at the + client (C). The corresponding timing is 0 seconds, which means + that this is the start of the run. The request was 462 bytes + long and started with tt(GET http://public...) + it() Line 2: 0.052974 seconds later, the backend (B) replied + with tt(HTTP/1.1 200 OK). + + it() Lines 3, 4 and 5: The backend (B) proceeded by sending + chunks.) + + The buffer sizes (462, 394 and so on) also tell us that the + network sends relatively small chunks. In this case we might save + some processing memory by setting the TCP buffer size to say 2K, + instead of the default 5K. In this situation, most of the default + 5K buffers will be unused. Setting the TCP buffer size to 2K can be done + using the flag tt(-B 2048) or by using the statement + tt(tcpbuffersize) tt(2048;) in an tt(options) block of the configuration. + It is also worth while remembering that the start time of a bf(C) request is the time that crossroads sees the activity. Any latency between the true client and crossroads is obviously not @@ -95,7 +90,7 @@ client ---->---->---->--->*crossroads ====>====>====> client ----<----<----<---< crossroads ====<====<====< ) - This simple picture shows a typical HTTP request that originates + This simple picture shows a typical request that originates at a client, travels to crossroads, and is relayed via the back end. The bf(C) entry in a throughput log is the time when crossroads sees the request, indicated by an asterisk. The bf(B) @@ -105,8 +100,8 @@ client ----<----<----<---< crossroads ====<====<====< the throughput log: the latency between client and crossroads isn't included in that measurement. - Summarizing, the throughput times of a client-back end connection - can be analyzed using the directive tt(throughputlog). In a - real-world analysis, you'd probably want to write up a script to - analyze the output and to compute round trip times. Such scripts - are not (yet) included in Crossroads. + Summarizing, the throughput times and buffer sizes of a + client-back end connection can be analyzed using the directive + tt(throughputlog). In a real-world analysis, you'd probably want + to write up a script to analyze the output and to compute round + trip times. Such scripts are not (yet) included in Crossroads. diff --git a/doc/man/crossroads.yo b/doc/man/crossroads.yo @@ -60,7 +60,7 @@ manpageoptions() it() bf(-d) em(sec): Sets the DNS cache time-to-live to em(sec) seconds. Value 0 suppresses DNS entry caching. The default is bf(DNSCACHETTL()). - + it() bf(-l) em(facility): Specifies the openlog (3) facility, default is bf(LOG_DAEMON). Values can be 0 to 7, meaning bf(LOG_LOCAL0) to bf(LOG_LOCAL9). @@ -87,7 +87,7 @@ manpageoptions() it() bf(-V): Shows the version ID and stops. - it() bf(-?, -h): Shows an overview of the usage.) + it() bf(-?): Shows an overview of the usage.) manpagefiles() bf(DEFAULTCONF()), the default configuration file diff --git a/etc/Makefile.conf b/etc/Makefile.conf @@ -40,4 +40,6 @@ DEFS := -DDEFAULT_CONF='"$(DEFAULT_CONF)"' \ $(shell $(BASE)/tools/c-conf -c $(BASE)/src/c-conf.cache \ libfunction01 strupr HAVE_STRUPR) \ $(shell $(BASE)/tools/c-conf -c $(BASE)/src/c-conf.cache \ + libfunction01 strnstr HAVE_STRNSTR) \ + $(shell $(BASE)/tools/c-conf -c $(BASE)/src/c-conf.cache \ libvariable01 __progname_full HAVE_PROGNAME_FULL) 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.71 +VER = 1.75 # Years that Crossroads has been 'round. YEARS = 2005-2007 diff --git a/etc/Makefile.help b/etc/Makefile.help @@ -5,11 +5,11 @@ Make what? Choose: ** Local Construction ** - make local Local program construction; src/crossroads will - be built - make local-g Local program construction wigh 'gdb' symbols - make local-pg Local program construction with 'gprof' style - profiling information included + make compile-only Local program construction (src/crossroads/crossroads + and src/crossroads-daemon/crossroads-daemon) + make local Local program construction and unit tests + make local-g Like 'make local' but wigh 'gdb' symbols + make local-pg Like 'make local-g' but with 'gprof' profiling make documentation Creates documentation under doc/. Requires Yodl and pdflatex. diff --git a/etc/svnrev b/etc/svnrev @@ -12,7 +12,7 @@ die ("No such file $ARGV[0]\n") my $revno; # Can we slurp in "svn info"? -if (open (my $if, "svn info $ARGV[0] |")) { +if (open (my $if, "svn info $ARGV[0] 2>&1 |")) { while (defined (my $line = <$if>)) { chomp ($line); next unless ($line =~ /Last Changed Rev:/); diff --git a/etc/svnrev.txt b/etc/svnrev.txt @@ -1 +1 @@ -214 +224 diff --git a/src/crossroads-daemon/Makefile b/src/crossroads-daemon/Makefile @@ -25,5 +25,4 @@ $(BIN): main.o ../lib/libcrossroads.a # Extra deps: -main.o: main.c $(BASE)/src/crossroads.h $(BASE)/etc/Makefile.def \ - ../shared/parseopt.inc +main.o: main.c $(BASE)/src/crossroads.h $(BASE)/etc/Makefile.def +\ No newline at end of file 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.71, a load balancer and fail over + * This file is part of Crosroads 1.75, a load balancer and fail over * utility for TCP. Copyright (c) Karel Kubat, distributed under GPL. * Visit http://crossroads.e-tunity.com for information. *************************************************************************/ @@ -7,19 +7,48 @@ #include "../crossroads.h" int main (int argc, char **argv) { - int opt, i; + int i; /* Remember original ac/av/ep */ org_argc = argc; org_argv = argv; - /* Parse the command line. */ - #define TARGET_CROSSROADS_DAEMON - #include "../shared/parseopt.inc" - - /* We're the daemon executable. We know what to do -- serve. */ - create_commandline_space(); + /* Inherit program options and configuration */ + options_read (0); config_read (0); + + /* Convert the log facility number into a syslog constant. */ + switch (opt.log_facility) { + case 0: + opt.log_facility = LOG_LOCAL0; + break; + case 1: + opt.log_facility = LOG_LOCAL1; + break; + case 2: + opt.log_facility = LOG_LOCAL2; + break; + case 3: + opt.log_facility = LOG_LOCAL3; + break; + case 4: + opt.log_facility = LOG_LOCAL4; + break; + case 5: + opt.log_facility = LOG_LOCAL5; + break; + case 6: + opt.log_facility = LOG_LOCAL6; + break; + case 7: + opt.log_facility = LOG_LOCAL7; + break; + default: + opt.log_facility = LOG_DAEMON; + break; + } + + /* We're the daemon executable. We know what to do -- serve. */ msg ("Starting services"); for (i = 0; i < nservice; i++) { /* Start the service. */ diff --git a/src/crossroads.h b/src/crossroads.h @@ -1,5 +1,5 @@ /************************************************************************* - * This file is part of Crosroads 1.71, a load balancer and fail over + * This file is part of Crosroads 1.75, a load balancer and fail over * utility for TCP. Copyright (c) Karel Kubat, distributed under GPL. * Visit http://crossroads.e-tunity.com for information. *************************************************************************/ @@ -10,7 +10,6 @@ #endif /* Includes. */ - #include <ctype.h> #include <errno.h> #include <fcntl.h> @@ -64,6 +63,19 @@ /* Types. */ +/* NOTE: Adapt optionsread.c and data.c and parser.y when changing! + * -------------------------------------------------------------- */ +typedef struct { /* Operating options in daemon */ + int log_activity; /* -a: log TCP timings? */ + unsigned tcp_bufsz; /* -B: TCP buffer size */ + int dns_cachettl; /* -d: DNS cache timeout */ + int log_facility; /* -l: logging facility */ + int shmperm; /* -m: SHM permissions */ + int sloppyportbind; /* -s: sloppy port bindings? */ + int leave_proctitle; /* -p: leave process title? */ + int log_http_activity; /* -h: log HTTP activity? */ +} Options; + typedef struct { /* Symbol table for #define */ char *symbol; char *redef; @@ -97,6 +109,7 @@ typedef enum { /* Config parsing related */ cf_inspectionspec, cf_dumpspec, cf_thruspec, + cf_httptimingspec, cf_bindspec, cf_stickycookiespec, cf_setclientheaderspec, @@ -168,6 +181,7 @@ typedef struct { /* Backend description */ char *onend; /* .. or on ending */ char *dumpfile; /* .. traffic dump file */ char *thruputfile; /* .. traffic throughput file */ + char *timinglog; /* .. HTTP timings log */ unsigned maxconnections; /* .. max # of allowed connections */ char *stickycookie; /* .. cookie selector */ int retries; /* .. # retries before unavailable */ @@ -197,7 +211,7 @@ typedef enum { /* HTTP header inspection mode */ } HttpInspection; /* The configuration in internal representation. When changing, remember - * to change config_write() and config_read()! */ + * to change config_write() and config_read() and config_msg()! */ typedef struct { /* Service description */ /* Basic stuff */ char *name; /* .. service name */ @@ -313,17 +327,15 @@ EXTERN DnsCache dnscache[]; /* DNS cache */ EXTERN int dns_cachettl; /* TTL of DNS cache entries */ EXTERN int flag_verbose; /* flag: verbosity */ EXTERN int gid_org, gid_set; /* original gid, flag: changed? */ -EXTERN int iflag_present; /* flag: -i present */ EXTERN int interrupted; /* got a signal? */ EXTERN char *laststring; /* semantic lexer value */ -EXTERN int leave_proctitle; /* don't modify process title flag */ EXTERN int listen_sock; /* servicer listening socket */ -EXTERN int log_activity; /* log activy to syslog? */ -EXTERN int log_facility; /* openlog(3) facility, -l flag */ EXTERN int logstarted; /* was syslog() called yet? */ EXTERN int nservice; /* # service descriptions */ +EXTERN Options opt; /* processing options */ EXTERN int org_argc; /* original argc */ EXTERN char **org_argv; /* and original argv */ +EXTERN int parser_debug; /* lexer/parser debugging */ EXTERN ParserState *parserstate; /* parser state */ EXTERN int nparserstate; /* size of array */ EXTERN Programstage program_stage; /* stage of the program */ @@ -332,8 +344,6 @@ EXTERN int reload_allow_deny; /* flag to reload spec files */ EXTERN int semid; /* semaphore ID */ EXTERN Service *service; /* service descriptions */ EXTERN Servicereport *servicereport; /* reporter in shared mem */ -EXTERN int shmperm; /* shm permissions, default 0644 */ -EXTERN int sloppyportbind; /* -s flag present */ EXTERN unsigned char *srbuf; /* server socket input buffer */ EXTERN int srbufpos, srbufmax; /* .. position & bytes */ EXTERN StateStringMap /* state/string map */ @@ -341,7 +351,6 @@ 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 char *xml_xslt; /* -X: XSLT refrence for XML output */ @@ -368,10 +377,10 @@ extern int cmd_start (int ac, char **av); extern int cmd_stop (int ac, char **av); extern int cmd_tell (int ac, char **av); extern int cmd_configtest (int ac, char **av); +extern void config_msg (void); extern void config_read (int fd); extern void config_write (int fd); extern void copysockets (int clientsock, int serversock); -extern void create_commandline_space (void); extern void decr_client_count (void); extern void dealloc_reporter (Service *s); extern struct in_addr *dns (char const *hostname); @@ -394,6 +403,7 @@ extern HttpHeader *http_header_new (void); extern void http_header_read (HttpHeader *m, int srcsock, CopyDirection dir); extern void http_header_setheader (HttpHeader *m, char const *hdr); extern void http_header_write (HttpHeader *m, int sock, CopyDirection dir); +extern void http_log_activity (double start, double end, char const *fmt, ...); extern void http_serve (int clientsock); extern int http_serversocket (HttpHeader *m, int *is_continuation); extern int http_write (int sock, CopyDirection dir, unsigned char const *buf, @@ -431,6 +441,8 @@ extern unsigned char *net_bufread (int sock, int maxbytes, int *nreadp, int is_client); extern int net_write (int sock, unsigned char const *buf, int len, int is_client); +extern void options_read (int fd); +extern void options_write (int fd); extern int parser_close(); extern char const *parser_filename(void); extern void parser_open (char const *name); @@ -455,6 +467,7 @@ extern void symtab_set (char const *symbol); extern void symtab_start (char const *symbol); extern int sysrun (char const *cmd); extern void tcpserve (int sock); +extern double timeofday(void); extern void thruputlog (unsigned char const *buf, int len, CopyDirection dir); extern void trafficlog (unsigned char const *buf, int len, CopyDirection dir); extern void unlock_reporter (void); @@ -499,6 +512,11 @@ extern void setproctitle (char const *fmt, ...); extern char *strupr (char *buf); #endif +/* strnstr() if it's missing on this system */ +#if HAVE_STRNSTR == 0 +extern char *strnstr (char const *buf, char const *little, unsigned len); +#endif + /* __progname_full on systems that have it */ #if HAVE_PROGNAME_FULL == 1 extern char *__progname_full; diff --git a/src/crossroads/Makefile b/src/crossroads/Makefile @@ -24,6 +24,5 @@ $(BIN): main.o ../lib/libcrossroads.a $(LIBS) $(EXTRALIBS) # Extra deps: -main.o: main.c $(BASE)/src/crossroads.h $(BASE)/etc/Makefile.def \ - ../shared/parseopt.inc +main.o: main.c $(BASE)/src/crossroads.h $(BASE)/etc/Makefile.def diff --git a/src/crossroads/main.c b/src/crossroads/main.c @@ -1,5 +1,5 @@ /************************************************************************* - * This file is part of Crosroads 1.71, a load balancer and fail over + * This file is part of Crosroads 1.75, 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,9 @@ typedef struct { } Handler; int main (int argc, char **argv) { - int opt; - unsigned i; + int o; + unsigned i; + int dumpconf = 0; static Handler handler[] = { /* Argument Nr.args Needconf Handler function */ /* -1=no check */ @@ -32,10 +33,79 @@ int main (int argc, char **argv) { org_argc = argc; org_argv = argv; - /* Parse the command line. */ - #define TARGET_CROSSROADS - #include "../shared/parseopt.inc" + /* Parse the command line. + * NOTE: When changing the options list, remember to update: + * - src/lib/usage.txt + * - doc/main/using.yo + * - doc/man/crossroads.yo + */ + while ( (o = getopt (argc, argv, "bB:?c:fhvVal:stCm:xd:X:pP")) > 0 ) + switch (o) { + case 'a': + opt.log_activity++; + break; + case 'b': + dumpconf++; + break; + case 'B': + opt.tcp_bufsz = atoi (optarg); + break; + case 'c': + config_file = optarg; + break; + case 'd': + opt.dns_cachettl = atoi (optarg); + break; + case 'v': + flag_verbose++; + break; + case 'l': + opt.log_facility = atoi(optarg); + break; + case 'm': + opt.shmperm = strtol (optarg, 0, 8); + break; + case 's': + opt.sloppyportbind++; + break; + case 't': + tabular_status++; + break; + case 'x': + xml_status++; + break; + case 'X': + xml_xslt = optarg; + break; + case 'C': + show_config(); + exit (0); + case 'p': + opt.leave_proctitle++; + break; + case 'P': + parser_debug++; + break; + case 'V': + puts (VER); + exit (0); + case '?': + case 'h': + default: + usage (); + } + /* Request to dump binary configuration? */ + if (dumpconf) { + msg ("Parsing configuration %s", config_file); + parser_open (config_file); + parser_run(); + parser_close(); + options_write (1); + config_write (1); + exit (0); + } + /* We need at last one argument: the action */ if (optind >= argc) usage(); diff --git a/src/lib/Makefile b/src/lib/Makefile @@ -52,3 +52,5 @@ strexpandformat.o: strexpandformat.c $(BASE)/etc/Makefile.def showconfig.o: showconfig.c $(BASE)/etc/Makefile.def Makefile data.o: data.c $(BASE)/src/crossroads.h usage.o: usage.c usage.h +optionswrite.o: optionswrite.c ../crossroads.h +optionsread.o: optionsread.c ../crossroads.h diff --git a/src/lib/allocreporter.c b/src/lib/allocreporter.c @@ -1,5 +1,5 @@ /************************************************************************* - * This file is part of Crosroads 1.71, a load balancer and fail over + * This file is part of Crosroads 1.75, 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,7 +24,7 @@ void alloc_reporter (Service *s, int first) { if (first) { /* First time 'round. We're allocating for the first time here.*/ if ( (shmid = shmget (s->shmkey, REPORTSIZE(s), - shmperm | IPC_CREAT) ) >= 0) + opt.shmperm | IPC_CREAT) ) >= 0) msg ("Created new shm at id %d", shmid); else error ("Cannot create shared memory for service %s (key %d: %s)", @@ -40,7 +40,7 @@ void alloc_reporter (Service *s, int first) { error ("Failed to set status of shared memory: %s", strerror(errno)); - if ( (semid = semget (s->shmkey, 1, shmperm | IPC_CREAT)) >= 0 ) + if ( (semid = semget (s->shmkey, 1, opt.shmperm | IPC_CREAT)) >= 0 ) msg ("Created new sem at id %d", semid); else error ("Cannot create semaphore for service %s (key %d: %s)", @@ -48,14 +48,14 @@ void alloc_reporter (Service *s, int first) { } else { /* Second time 'round. We're getting a handle on previously * created shared memory and semaphores. */ - if ( (shmid = shmget (s->shmkey, REPORTSIZE(s), shmperm) ) >= 0 ) + if ( (shmid = shmget (s->shmkey, REPORTSIZE(s), opt.shmperm) ) >= 0 ) msg ("Got existing shm at id %d", shmid); else error ("Cannot get shared memory for service %s, key %d: %s. " "Maybe crossroads isn't running, or the configuration " "has changed.", s->name, s->shmkey, strerror(errno)); - if ( (semid = semget (s->shmkey, 1, shmperm)) >= 0 ) + if ( (semid = semget (s->shmkey, 1, opt.shmperm)) >= 0 ) msg ("Got existing sem at id %d", semid); else error ("Cannot get semaphore for service %s (key %d: %s)", diff --git a/src/lib/ansistamp.c b/src/lib/ansistamp.c @@ -1,5 +1,5 @@ /************************************************************************* - * This file is part of Crosroads 1.71, a load balancer and fail over + * This file is part of Crosroads 1.75, 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.71, a load balancer and fail over + * This file is part of Crosroads 1.75, a load balancer and fail over * utility for TCP. Copyright (c) Karel Kubat, distributed under GPL. * Visit http://crossroads.e-tunity.com for information. *************************************************************************/ @@ -16,12 +16,12 @@ int backend_available (int target) { (activeservice->backend[target].maxconnections == 0 || activeservice->backend[target].maxconnections > servicereport->backendstate[target].nclients)) { - msg ("Service %s: target nr %d is available", - activeservice->name, target); + msg ("Service %s: backend %s is available", + activeservice->name, activeservice->backend[target].name); return (1); } - msg ("Service %s: target nr %d is unavailable", - activeservice->name, target); + msg ("Service %s: backend %s is unavailable", + activeservice->name, activeservice->backend[target].name); return (0); } diff --git a/src/lib/backendconnect.c b/src/lib/backendconnect.c @@ -1,5 +1,5 @@ /************************************************************************* - * This file is part of Crosroads 1.71, a load balancer and fail over + * This file is part of Crosroads 1.75, 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.71, a load balancer and fail over + * This file is part of Crosroads 1.75, 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/checkservice.c b/src/lib/checkservice.c @@ -1,5 +1,5 @@ /************************************************************************* - * This file is part of Crosroads 1.71, a load balancer and fail over + * This file is part of Crosroads 1.75, 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.71, a load balancer and fail over + * This file is part of Crosroads 1.75, a load balancer and fail over * utility for TCP. Copyright (c) Karel Kubat, distributed under GPL. * Visit http://crossroads.e-tunity.com for information. *************************************************************************/ @@ -70,11 +70,16 @@ void choose_backend () { backends[nbackends++] = i; } } + + /* When we don't have any active back ends, then we sleep a bit. */ + if (!nbackends) + sleep (RETRY_WAIT); - /* No backends? Nogo. */ - if (!nbackends) { + /* No backends? Nogo. Unless there is external dispatching. */ + if (nbackends == 0 && activeservice->dispatchtype != ds_externalhandler) { current_backend = -1; - warning ("No active backends to select!"); + warning ("Service %s: No active backends to select!", + activeservice->name); return; } @@ -353,7 +358,8 @@ void choose_backend () { return; case ds_externalhandler: - /* External handler to be called */ + /* External handler to be called. Assume selection will fail. */ + current_backend = -1; exthandler = str_expand_format (activeservice->dispatchext); msg ("Service %s: calling external handler '%s'", activeservice->name, exthandler); @@ -361,10 +367,14 @@ void choose_backend () { if (! (f = popen (exthandler, "r")) ) { warning ("Service %s: failed to start external handler '%s': %s", activeservice->name, exthandler, strerror(errno)); - current_backend = backends[0]; - servicereport->last_backend = current_backend; + if (nbackends > 0) { + current_backend = backends[0]; + servicereport->last_backend = current_backend; + } + uid_restore(); free (backends); + free (exthandler); return; } while (1) { @@ -377,23 +387,27 @@ void choose_backend () { } msg ("Service %s: external handler says '%s'", activeservice->name, buf); - for (i = 0; i < nbackends; i++) - if (!strcmp (buf, activeservice->backend[backends[i]].name)) { + for (i = 0; i < activeservice->nbackend; i++) { + if (!strcmp (buf, activeservice->backend[i].name)) { msg ("Service %s: selecting back end %s due to " "external handler", activeservice->name, buf); - current_backend = backends[i]; + current_backend = i; servicereport->last_backend = current_backend; pclose (f); uid_restore(); free (backends); + free (exthandler); return; } + } } - warning ("Service %s: external handler didn't reply with " - "a selectable back end", activeservice->name); - current_backend = backends[0]; + warning ("Service %s: external handler '%s' didn't reply with " + "a selectable back end", activeservice->name, exthandler); + if (nbackends > 0) + current_backend = backends[0]; servicereport->last_backend = current_backend; free (backends); + free (exthandler); return; default: diff --git a/src/lib/cmdconfigtest.c b/src/lib/cmdconfigtest.c @@ -1,5 +1,5 @@ /************************************************************************* - * This file is part of Crosroads 1.71, a load balancer and fail over + * This file is part of Crosroads 1.75, 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/cmdrestart.c b/src/lib/cmdrestart.c @@ -1,5 +1,5 @@ /************************************************************************* - * This file is part of Crosroads 1.71, a load balancer and fail over + * This file is part of Crosroads 1.75, a load balancer and fail over * utility for TCP. Copyright (c) Karel Kubat, distributed under GPL. * Visit http://crossroads.e-tunity.com for information. *************************************************************************/ @@ -7,8 +7,6 @@ int cmd_restart (int ac, char **av) { - create_commandline_space(); - /* First run the 'stop' action. */ if (!cmd_stop (ac, av)) error ("Daemon stop failed, restart failure"); diff --git a/src/lib/cmdservices.c b/src/lib/cmdservices.c @@ -1,5 +1,5 @@ /************************************************************************* - * This file is part of Crosroads 1.71, a load balancer and fail over + * This file is part of Crosroads 1.75, 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/cmdstart.c b/src/lib/cmdstart.c @@ -1,5 +1,5 @@ /************************************************************************* - * This file is part of Crosroads 1.71, a load balancer and fail over + * This file is part of Crosroads 1.75, a load balancer and fail over * utility for TCP. Copyright (c) Karel Kubat, distributed under GPL. * Visit http://crossroads.e-tunity.com for information. *************************************************************************/ @@ -7,20 +7,27 @@ #include "../crossroads.h" int cmd_start (int ac, char **av) { - int i; FILE *f; char *cmd; + /* Prepare the command to run. When the process title may be modified, + * reserve space. */ cmd = xstrdup (BINDIR "/crossroads-daemon"); + if (!opt.leave_proctitle) + cmd = xstrcat (cmd, " xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" + "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"); + + /* for (i = 1; i < org_argc; i++) { cmd = xstrcatch (cmd, ' '); cmd = xstrcat (cmd, org_argv[i]); - } - - msg ("Starting daemon"); + } + msg ("Starting daemon (%s), cmd"); + */ if (! (f = popen (cmd, "w")) ) error ("Failed to start %s: %s", cmd, strerror(errno)); + options_write (fileno(f)); config_write (fileno(f)); if (pclose (f) == -1) error ("Crossroads daemon '%s' indicates error", cmd); diff --git a/src/lib/cmdstatus.c b/src/lib/cmdstatus.c @@ -1,5 +1,5 @@ /************************************************************************* - * This file is part of Crosroads 1.71, a load balancer and fail over + * This file is part of Crosroads 1.75, 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/cmdstop.c b/src/lib/cmdstop.c @@ -1,5 +1,5 @@ /************************************************************************* - * This file is part of Crosroads 1.71, a load balancer and fail over + * This file is part of Crosroads 1.75, 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/cmdtell.c b/src/lib/cmdtell.c @@ -1,5 +1,5 @@ /************************************************************************* - * This file is part of Crosroads 1.71, a load balancer and fail over + * This file is part of Crosroads 1.75, 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/configmsg.c b/src/lib/configmsg.c @@ -0,0 +1,144 @@ +/************************************************************************* + * This file is part of Crosroads 1.75, 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" + +#define MSGSTR(x,y) msg(x ": [%s]", y) +#define MSGUNS(x,y) msg(x ": [%u]", y) +#define MSGINT(x,y) msg(x ": [%d]", y) + +#define BMSGSTR(x,y,z) msg("Backend %d: " y " [%s]", x + 1, z) +#define BMSGINT(x,y,z) msg("Backend %d: " y " [%d]", x + 1, z) +#define BMSGUNS(x,y,z) msg("Backend %d: " y " [%u]", x + 1, z) + +static char *dispatchstr (Dispatchtype t) { + switch (t) { + case ds_roundrobin: + return ("roundrobin"); + case ds_random: + return ("random"); + case ds_bysize: + return ("bysize"); + case ds_byduration: + return ("byduration"); + case ds_byorder: + return ("byorder"); + case ds_byconnections: + return ("byconnections"); + case ds_byclientip: + return ("byclientip"); + case ds_externalhandler: + return ("externalhandler"); + default: + return ("*** cannot display ***"); + } +} + +static char *servicestr (Servicetype t) { + switch (t) { + case type_any: + return ("any"); + case type_http: + return ("http"); + default: + return ("*** cannot display ***"); + } +} + +static char *inspectionstr (HttpInspection t) { + switch (t) { + case ins_deep: + return ("deep"); + case ins_shallow: + return ("shallow"); + default: + return ("*** cannot display ***"); + } +} + +static void headers (int nr, char **hdr, int nhdr, char *desc) { + int i; + + msg ("Backend %d: %d %s header(s)", nr + 1, nhdr, desc); + for (i = 0; i < nhdr; i++) + msg ("Backend %d: %s #%d: %s", nr + 1, desc, i + 1, hdr[i]); +} + +void config_msg () { + int i; + + if (!activeservice->verbosity) + return; + + msg ("*** Overview of initial configuration of service '%s' ***", + activeservice->name); + MSGSTR ("Bind address", activeservice->bind); + MSGUNS ("Bind port", activeservice->port); + MSGUNS ("Verbosity", activeservice->verbosity); + MSGSTR ("Dispatch type", dispatchstr (activeservice->dispatchtype)); + MSGSTR ("External handler", activeservice->dispatchext); + MSGUNS ("Reviving interval", activeservice->rev_interval); + MSGUNS ("Check interval", activeservice->check_interval); + MSGSTR ("External checker", activeservice->check_cmd); + MSGUNS ("TCP backlog", activeservice->backlog); + MSGUNS ("SHM key", activeservice->shmkey); + MSGUNS ("Connection timeout", activeservice->connectiontimeout); + MSGUNS ("Max connections", activeservice->maxconnections); + MSGSTR ("Service type", servicestr (activeservice->type)); + MSGSTR ("HTTP inspection", inspectionstr (activeservice->inspection)); + MSGSTR ("Allow file", activeservice->allowfile); + MSGSTR ("Deny file", activeservice->denyfile); + MSGINT ("UID", activeservice->uid); + MSGINT ("GID", activeservice->gid); + MSGINT ("Initial deny chain", activeservice->ndenychain); + for (i = 0; i < activeservice->ndenychain; i++) + msg ("Deny #%d: %4.4x/%4.4x", i + 1, activeservice->denychain[i].ip, + activeservice->denychain[i].mask); + MSGINT ("Initial allow chain", activeservice->nallowchain); + for (i = 0; i < activeservice->nallowchain; i++) + msg ("Allow #%d: %4.4x/%4.4x", i + 1, activeservice->allowchain[i].ip, + activeservice->allowchain[i].mask); + MSGINT ("Back ends", activeservice->nbackend); + + for (i = 0; i < activeservice->nbackend; i++) { + BMSGSTR (i, "name", activeservice->backend[i].name); + BMSGINT (i, "port", activeservice->backend[i].initial_port); + BMSGSTR (i, "server", activeservice->backend[i].initial_server); + BMSGINT (i, "verbosity", activeservice->backend[i].verbosity); + BMSGINT (i, "weight", activeservice->backend[i].weight); + BMSGINT (i, "decay", activeservice->backend[i].decay); + BMSGSTR (i, "onstart cmd", activeservice->backend[i].onstart); + BMSGSTR (i, "onfail cmd", activeservice->backend[i].onfail); + BMSGSTR (i, "onend cmd", activeservice->backend[i].onend); + BMSGSTR (i, "dumplog", activeservice->backend[i].dumpfile); + BMSGSTR (i, "thruputlog", activeservice->backend[i].thruputfile); + BMSGSTR (i, "timinglog", activeservice->backend[i].timinglog); + BMSGUNS (i, "maxconnections", activeservice->backend[i].maxconnections); + BMSGSTR (i, "stickycookie", activeservice->backend[i].stickycookie); + BMSGINT (i, "retries", activeservice->backend[i].retries); + headers (i, activeservice->backend[i].addclientheader, + activeservice->backend[i].naddclientheader, + "addclientheader"); + headers (i, activeservice->backend[i].setclientheader, + activeservice->backend[i].nsetclientheader, + "setclientheader"); + headers (i, activeservice->backend[i].appendclientheader, + activeservice->backend[i].nappendclientheader, + "appendclientheader"); + headers (i, activeservice->backend[i].addserverheader, + activeservice->backend[i].naddserverheader, + "addserverheader"); + headers (i, activeservice->backend[i].setserverheader, + activeservice->backend[i].nsetserverheader, + "setserverheader"); + headers (i, activeservice->backend[i].appendserverheader, + activeservice->backend[i].nappendserverheader, + "appendserverheader"); + BMSGSTR (i, "availability", + state_to_string (activeservice->backend[i].initial_avail)); + } +} + diff --git a/src/lib/configread.c b/src/lib/configread.c @@ -1,5 +1,5 @@ /************************************************************************* - * This file is part of Crosroads 1.71, a load balancer and fail over + * This file is part of Crosroads 1.75, a load balancer and fail over * utility for TCP. Copyright (c) Karel Kubat, distributed under GPL. * Visit http://crossroads.e-tunity.com for information. *************************************************************************/ @@ -110,6 +110,7 @@ void config_read (int fd) { service[i].backend[j].onend = rd_str (fd); service[i].backend[j].dumpfile = rd_str (fd); service[i].backend[j].thruputfile = rd_str (fd); + service[i].backend[j].timinglog = rd_str (fd); service[i].backend[j].maxconnections = rd_uns (fd); service[i].backend[j].stickycookie = rd_str (fd); service[i].backend[j].retries = rd_int (fd); diff --git a/src/lib/configwrite.c b/src/lib/configwrite.c @@ -1,5 +1,5 @@ /************************************************************************* - * This file is part of Crosroads 1.71, a load balancer and fail over + * This file is part of Crosroads 1.75, a load balancer and fail over * utility for TCP. Copyright (c) Karel Kubat, distributed under GPL. * Visit http://crossroads.e-tunity.com for information. *************************************************************************/ @@ -86,6 +86,7 @@ void config_write (int fd) { wr_str (fd, service[i].backend[j].onend); wr_str (fd, service[i].backend[j].dumpfile); wr_str (fd, service[i].backend[j].thruputfile); + wr_str (fd, service[i].backend[j].timinglog); wr_uns (fd, service[i].backend[j].maxconnections); wr_str (fd, service[i].backend[j].stickycookie); wr_int (fd, service[i].backend[j].retries); diff --git a/src/lib/copysockets.c b/src/lib/copysockets.c @@ -1,17 +1,17 @@ /************************************************************************* - * This file is part of Crosroads 1.71, a load balancer and fail over + * This file is part of Crosroads 1.75, 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 = xmalloc (tcp_bufsz); + unsigned char *buf = xmalloc (opt.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. * So there isn't even a reason to free(buf). */ while (1) - net_copy (clientsock, serversock, tcp_bufsz, buf); + net_copy (clientsock, serversock, opt.tcp_bufsz, buf); } diff --git a/src/lib/createcommandlinespace.c b/src/lib/createcommandlinespace.c @@ -1,44 +0,0 @@ -/************************************************************************* - * This file is part of Crosroads 1.71, 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 create_commandline_space () { - char **argv; - int i; - - /* Here's a dirty hack for Linux systems. We're going to get - * daemonized and we'll want to change the - * program name as it appears in the ps list. - * So we re-exec ourselves with a dummy -i flag that creates - * space on the commanedline. The exec'd process then has more space - * to fiddle around with the process name. - */ -# if SET_PROC_TITLE_BY_ARGV == 1 - - /* Don't proceed if we are not going to change process titles - * or if -i xxxx was already specified. */ - if (leave_proctitle || iflag_present) - return; - - msg ("Re-execing for command line space"); - argv = xmalloc ( (org_argc + 2) * sizeof(char*)); - - argv[0] = org_argv[0]; - argv[1] = "-ixxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" - "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"; - argv[org_argc + 1] = 0; - - for (i = 1; i < org_argc; i++) - argv[i + 1] = org_argv[i]; - argv[org_argc + 1] = 0; - - execv (argv[0], argv); - execvp (argv[0], argv); - error ("Failed to re-exec program: %s", - strerror(errno)); - -# endif -} diff --git a/src/lib/data.c b/src/lib/data.c @@ -1,5 +1,5 @@ /************************************************************************* - * This file is part of Crosroads 1.71, a load balancer and fail over + * This file is part of Crosroads 1.75, a load balancer and fail over * utility for TCP. Copyright (c) Karel Kubat, distributed under GPL. * Visit http://crossroads.e-tunity.com for information. *************************************************************************/ @@ -9,11 +9,18 @@ /* Global data for all Crossroads programs */ -int log_facility = LOG_DAEMON; -int shmperm = 0644; -int dns_cachettl = DNS_CACHETTL; +Options opt = { + 0, /* log_activity */ + DEFAULT_TCP_BUFSZ, /* tcp_bufsz */ + DNS_CACHETTL, /* dns_cachettl */ + LOG_DAEMON, /* log_facility */ + + 0644, /* shmperm */ + 0, /* sloppyportbind */ + 0, /* leave_proctitle */ +}; + 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.71, a load balancer and fail over + * This file is part of Crosroads 1.75, 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.71, a load balancer and fail over + * This file is part of Crosroads 1.75, 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.71, a load balancer and fail over + * This file is part of Crosroads 1.75, a load balancer and fail over * utility for TCP. Copyright (c) Karel Kubat, distributed under GPL. * Visit http://crossroads.e-tunity.com for information. *************************************************************************/ @@ -10,10 +10,13 @@ static int noncache_resolve (char const *hostname, struct in_addr *res) { struct hostent *hent; + double tick; + tick = timeofday(); if (! (hent = gethostbyname(hostname)) ) return (0); *res = *(struct in_addr *)hent->h_addr; + http_log_activity (tick, 0, "hostname resolved"); return (1); } diff --git a/src/lib/error.c b/src/lib/error.c @@ -1,5 +1,5 @@ /************************************************************************* - * This file is part of Crosroads 1.71, a load balancer and fail over + * This file is part of Crosroads 1.75, 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/gmtstamp.c b/src/lib/gmtstamp.c @@ -1,5 +1,5 @@ /************************************************************************* - * This file is part of Crosroads 1.71, a load balancer and fail over + * This file is part of Crosroads 1.75, a load balancer and fail over * utility for TCP. Copyright (c) Karel Kubat, distributed under GPL. * Visit http://crossroads.e-tunity.com for information. *************************************************************************/ diff --git a/src/lib/hashpjw.c b/src/lib/hashpjw.c @@ -1,5 +1,5 @@ /************************************************************************* - * This file is part of Crosroads 1.71, a load balancer and fail over + * This file is part of Crosroads 1.75, 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.71, a load balancer and fail over + * This file is part of Crosroads 1.75, a load balancer and fail over * utility for TCP. Copyright (c) Karel Kubat, distributed under GPL. * Visit http://crossroads.e-tunity.com for information. *************************************************************************/ @@ -22,8 +22,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 > opt.tcp_bufsz) + to_copy = opt.tcp_bufsz; buf = net_bufread (src, to_copy, &bytes, dir == dir_client_to_server); net_write (dst, buf, bytes, dir == dir_client_to_server); @@ -42,7 +42,7 @@ unsigned getchunk (int sock, int dest, CopyDirection dir) { int in_number = 1; /* We match - * <hex-chunksize> <any-mush> [\r] \n + * <hex-chunksize> <any-mush> [\r]\n * while copying all to the other socket, and return the * chunk size */ while (1) { @@ -53,7 +53,23 @@ unsigned getchunk (int sock, int dest, CopyDirection dir) { if (*cp == '\n') { sscanf (hexbuf, "%x", &ret); free (hexbuf); - /* msg ("Got chunk size 0x%x (%d)", ret, ret); */ + msg ("Service %s: Chunk size 0x%x (%d)", + activeservice->name, ret, ret); + /* If the chunk size is zero, then match final [\r]\n */ + if (ret == 0) { + cp = net_bufread (sock, 1, 0, dir == dir_client_to_server); + net_write (dest, cp, 1, dir == dir_client_to_server); + if (*cp == '\r') { + cp = net_bufread (sock, 1, 0, dir == dir_client_to_server); + net_write (dest, cp, 1, dir == dir_client_to_server); + if (*cp != '\n') + warning ("Service %s: Chunks not terminated by \\r\\n " + "but by \\r <decimal>%d", + activeservice->name, *cp); + } else if (*cp != '\n') + warning ("Service %s: Chunks not terminated by \r\n or \n " + "but by <decimal>%d", activeservice->name, *cp); + } return (ret); } if (in_number) { diff --git a/src/lib/httperror.c b/src/lib/httperror.c @@ -1,5 +1,5 @@ /************************************************************************* - * This file is part of Crosroads 1.71, a load balancer and fail over + * This file is part of Crosroads 1.75, 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.71, a load balancer and fail over + * This file is part of Crosroads 1.75, 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.71, a load balancer and fail over + * This file is part of Crosroads 1.75, 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.71, a load balancer and fail over + * This file is part of Crosroads 1.75, 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.71, a load balancer and fail over + * This file is part of Crosroads 1.75, 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.71, a load balancer and fail over + * This file is part of Crosroads 1.75, 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.71, a load balancer and fail over + * This file is part of Crosroads 1.75, 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.71, a load balancer and fail over + * This file is part of Crosroads 1.75, 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.71, a load balancer and fail over + * This file is part of Crosroads 1.75, a load balancer and fail over * utility for TCP. Copyright (c) Karel Kubat, distributed under GPL. * Visit http://crossroads.e-tunity.com for information. *************************************************************************/ @@ -21,7 +21,7 @@ static void debughdr (HttpHeader *h) { } #define SHOWHEADERS(h) debughdr((h)) -#define MSG(m) m +#define MSG(m) m; #else @@ -30,146 +30,91 @@ static void debughdr (HttpHeader *h) { #endif -/* Match a header (part) in a buffer. Return the header length. - * Stop at [\r]\n, or when the buffer length is reached. */ -int matchheader (unsigned char *const buf, int max) { - int i, len = 0; +void http_header_read (HttpHeader *h, int sock, CopyDirection dir) { + unsigned char *hdrbuf = 0, *start, *buf, *cp; + int hdrbuflen = 0, usedlen, *bufpos, *bufmax, i; - /* Loop over buffer */ - for (i = 0; i < max; i++) { - if (buf[i] == '\r' || buf[i] == '\n') - break; - len++; - } - MSG (msg("Next header length: %d in %s", len, buf);) - - return (len); -} + msg ("Service %s: reading HTTP headers from %s", + activeservice->name, + dir == dir_client_to_server ? "client" : "server"); -void http_header_read (HttpHeader *h, int sock, CopyDirection dir) { - unsigned char *buf; - int *curp, *maxp, hlen, append = 0, orglen; - - /* Set the dst ptrs */ + /* Read from network until we match [\r]\n[\r]\n */ if (dir == dir_client_to_server) { buf = clbuf; - curp = &clbufpos; - maxp = &clbufmax; - } - else { + bufpos = &clbufpos; + bufmax = &clbufmax; + } else { buf = srbuf; - curp = &srbufpos; - maxp = &srbufmax; + bufpos = &srbufpos; + bufmax = &srbufmax; } - - /* Get TCP octets until the headers are in. */ while (1) { - /* No buffer contents? TCP read. */ - if (! *maxp) { - *maxp = net_read (sock, tcp_bufsz, buf, - dir == dir_client_to_server); - MSG (msg("Service %s: Got %d bytes for headers in %s", - activeservice->name, *maxp, buf);) + if (! *bufmax) { + *bufmax = net_read (sock, opt.tcp_bufsz, buf, + dir == dir_client_to_server); + MSG(msg("Got %d network bytes (%s)", *bufmax, buf)); } - - /* Match a header (or a part of it). */ - if (! (hlen = matchheader (buf + *curp, *maxp - *curp)) ) { - /* Headers finished! */ - if (buf[*curp] == '\r') - (*curp)++; - if (buf[*curp] == '\n') - (*curp)++; - if (*curp == *maxp) { - *maxp = 0; - *curp = 0; - } + hdrbuf = xrealloc (hdrbuf, hdrbuflen + *bufmax); + memcpy (hdrbuf + hdrbuflen, buf + *bufpos, *bufmax); + hdrbuflen += *bufmax; + MSG(msg("Headers buffer so far: %d bytes (%s)", hdrbuflen, hdrbuf)); + + *bufmax = 0; + + /* Try to find header ending sequence */ + if ( (cp = strnstr ((char const *)hdrbuf, "\r\n\r\n", + (unsigned)hdrbuflen)) || + (cp = strnstr ((char const *)hdrbuf, "\n\n", + (unsigned)hdrbuflen)) ) { break; } + } - /* We have a header. Add it. */ - MSG (msg("Headers stored so far: %d", h->nheader);) - if (!append || h->nheader == 0) { - /* This part goes into a new header. */ - MSG (msg("Creating new header line over %d bytes (%s)", - hlen, buf + *curp);) - h->header = xrealloc (h->header, (h->nheader + 1) * sizeof (char*)); - h->header[h->nheader] = xmalloc (hlen + 1); - memcpy (h->header[h->nheader], buf + *curp, hlen); - h->header[h->nheader][hlen] = 0; - h->nheader++; - } else { - /* This part goes at the end of the current header. */ - MSG (msg("Appending %d bytes to header %s (%s)", - hlen, h->header[h->nheader - 1], buf + *curp);) - orglen = strlen(h->header [h->nheader - 1]); - h->header[h->nheader - 1] = - xrealloc (h->header[h->nheader - 1], orglen + hlen + 1); - memcpy (h->header[h->nheader - 1] + orglen, buf + *curp, hlen); - h->header[h->nheader - 1][orglen + hlen] = 0; - } + MSG(msg("Headers done, end at %s", cp)); - SHOWHEADERS(h); - - /* Skip over the processed header line and over [\r]\n. - * If \r\n occur then we won't append the next time around. */ - *curp += hlen; - MSG(msg("Advanced network buf to '%s'", buf + *curp);) - if (buf[*curp] == '\r') - MSG (msg("Skipped \\r");) - (*curp)++; - if (buf[*curp] == '\n') { - MSG (msg("Skipped \\n");) - (*curp)++; - append = 0; - } - if (*curp == *maxp) { - *maxp = 0; - *curp = 0; - } + /* Skip over the ending sequence and save remainder of buffer + * for next usage */ + for (i = 0; i < 2; i++) { + if (*cp == '\r') + cp++; + if (*cp == '\n') + cp++; } - -# ifdef DEBUG - msg ("Done reading headers"); - SHOWHEADERS(h); -# endif -} - -/* THE FOLLOWING IS THE PRE-1.69 CODE. IT WORKS BUT IS NOT CPU - * FRIENDLY. THE ABOVE CODE IS BETTER, BUT .... ALPHA - * I AM LEAVING THE OLD CODE FOR REFERENCE BELOW. - */ -#ifdef OLDCODE - -void http_header_read (HttpHeader *h, int sock, CopyDirection dir) { - unsigned char *cp; - int last_is_nl = 0, at_start = 1; - - msg ("Service %s: reading HTTP headers from %s", - activeservice->name, - dir == dir_client_to_server ? "client" : "server"); + usedlen = cp - hdrbuf; + if (usedlen < hdrbuflen) { + /* NOTE: We can always poke back the remainder, this is by definition + * not longer than opt.tcp_bufsize */ + memcpy (buf, cp, hdrbuflen - usedlen); + *bufpos = 0; + *bufmax = hdrbuflen - usedlen; + MSG(msg("Pushed back %d bytes (%s)", *bufmax, buf)); + } else { + *bufmax = 0; + MSG(msg("No remainding network for next read")); + } + + /* Split up the header buffer into separate headers and store them */ + start = hdrbuf; while (1) { - cp = net_bufread (sock, 1, 0, dir == dir_client_to_server); - /* msg ("http header read: got char %d (%c)", *cp, *cp); */ - /* SHOWHEADERS(h); */ - if (*cp == '\r') - continue; - if (*cp == '\n') { - if (last_is_nl && h->nheader) - break; - last_is_nl++; - continue; - } - if (at_start || last_is_nl) { + if (! (cp = memchr (start, '\r', usedlen - (start - hdrbuf))) ) + cp = memchr (start, '\n', usedlen - (start - hdrbuf)); + if (!cp) + break; + MSG(msg("Header %d: (%d bytes) at %s", h->nheader + 1, + cp - start, start)); + if (cp - start) { h->header = xrealloc (h->header, (h->nheader + 1) * sizeof(char*)); - h->header[h->nheader] = 0; + h->header[h->nheader] = xmalloc (cp - start + 1); + memcpy (h->header[h->nheader], start, cp - start); + h->header[h->nheader][cp - start] = 0; h->nheader++; - at_start = 0; } - h->header[h->nheader - 1] = xstrcatch (h->header[h->nheader - 1], *cp); - last_is_nl = 0; + start = cp + 1; + if (*start == '\n') + start++; } + + free (hdrbuf); SHOWHEADERS(h); } - -#endif /* OLDCODE */ diff --git a/src/lib/httpheaderremoveheader.c b/src/lib/httpheaderremoveheader.c @@ -1,5 +1,5 @@ /************************************************************************* - * This file is part of Crosroads 1.71, a load balancer and fail over + * This file is part of Crosroads 1.75, 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.71, a load balancer and fail over + * This file is part of Crosroads 1.75, 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.71, a load balancer and fail over + * This file is part of Crosroads 1.75, 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.71, a load balancer and fail over + * This file is part of Crosroads 1.75, 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.71, a load balancer and fail over + * This file is part of Crosroads 1.75, 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/httplogactivity.c b/src/lib/httplogactivity.c @@ -0,0 +1,50 @@ +/************************************************************************* + * This file is part of Crosroads 1.75, 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 http_log_activity (double start, double now, char const *fmt, ...) { + FILE *f; + va_list args; + + if (activeservice->type != type_http || program_stage == stage_retrying || + current_backend < 0 || + !activeservice->backend[current_backend].timinglog || + ! *activeservice->backend[current_backend].timinglog) + return; + + if (!now) + now = timeofday(); + if (! (f = fopen (activeservice->backend[current_backend].timinglog, + "a")) && + ! (f = fopen (activeservice->backend[current_backend].timinglog, + "w")) ) { + warning ("Service %s: cannot write HTTP timings log %s: %s", + activeservice->name, + activeservice->backend[current_backend].timinglog, + strerror(errno)); + return; + } + +#if HAVE_FLOCK == 1 + flock (fileno(f), LOCK_EX); +#elif HAVE_LOCKF === 1 + lockf (fileno(f), F_LOCK, 0); +#endif + + fprintf (f, "%7.7d %15f ", getpid(), now - start); + va_start (args, fmt); + vfprintf (f, fmt, args); + fputc ('\n', f); + +#if defined HAVE_FLOCK + flock (fileno(f), LOCK_UN); +#elif defined HAVE_LOCKF + lockf (fileno(f), F_ULOCK, 0); +#endif + + fclose (f); +} diff --git a/src/lib/httpserve.c b/src/lib/httpserve.c @@ -1,5 +1,5 @@ /************************************************************************* - * This file is part of Crosroads 1.71, a load balancer and fail over + * This file is part of Crosroads 1.75, a load balancer and fail over * utility for TCP. Copyright (c) Karel Kubat, distributed under GPL. * Visit http://crossroads.e-tunity.com for information. *************************************************************************/ @@ -9,16 +9,16 @@ void http_serve (int clientsock) { int serversock = -1, is_continuation, i; HttpHeader *clientreq, *serverresp; int client_persisting, server_persisting; - unsigned char *cp; - int size; + double cl_header_start, cl_header_end, + con_start, con_end, start, tcptotal, tick; /* Set relevant sigs etc. */ program_stage = stage_serving; for (i = 0; relevant_sigs[i]; i++) signal (relevant_sigs[i], interrupt); - if (!leave_proctitle) - setproctitle ("crossroads - Service %s: serving %s", - activeservice->name, client_ip); + + set_program_title ("crossroads - Service %s: serving %s", + activeservice->name, client_ip); /* We're the child branch now of fork_tcp_servicer(). * Here's the logic of the HTTP services. @@ -36,22 +36,33 @@ void http_serve (int clientsock) { net_allocbufs(); while (1) { + start = timeofday(); + tcptotal = 0; /* Reset network IO buffers. */ clbufpos = clbufmax = srbufpos = srbufmax = 0; /* Assume both client and server want to persist. */ client_persisting = server_persisting = 1; - /* Get the initial client headers */ + /* Get the initial client headers. We store the times but do + * not log yet, that can be done once we assign a back end. */ clientreq = http_header_new(); + cl_header_start = timeofday(); http_header_read (clientreq, clientsock, dir_client_to_server); + cl_header_end = timeofday(); + tcptotal += (cl_header_end - cl_header_start); /* Determine the back end if necessary. */ if (serversock == -1) { + con_start = timeofday(); if ( (serversock = http_serversocket (clientreq, &is_continuation)) < 1 ) http_error (clientsock); - + con_end = timeofday(); + http_log_activity (cl_header_start, cl_header_end, + "client headers received"); + http_log_activity (con_start, con_end, "connected to backend"); + tcptotal += (con_end - con_start); flag_verbose = activeservice->backend[current_backend].verbosity; incr_client_count(); @@ -94,14 +105,23 @@ void http_serve (int clientsock) { } /* Send client's headers to the back end. */ + tick = timeofday(); http_header_write (clientreq, serversock, dir_client_to_server); + tcptotal += timeofday() - tick; + http_log_activity (tick, 0, "sent clientheaders to backend"); /* Copy body from client to server */ + tick = timeofday(); http_copy (clientreq, clientsock, serversock, dir_client_to_server); + tcptotal += timeofday() - tick; + http_log_activity (tick, 0, "sent clientbody to backend"); /* Get server response. */ serverresp = http_header_new(); + tick = timeofday(); http_header_read (serverresp, serversock, dir_server_to_client); + tcptotal += timeofday() - tick; + http_log_activity (tick, 0, "received headers from backend"); /* Put client-directed headers in place. */ for (i = 0; @@ -153,15 +173,24 @@ void http_serve (int clientsock) { } /* Send server headers to the client. */ + tick = timeofday(); http_header_write (serverresp, clientsock, dir_server_to_client); + tcptotal += timeofday() - tick; + http_log_activity (tick, 0, "sent serverheaders to client"); /* Copy body from server to client and flush network buffers if any */ + tick = timeofday(); http_copy (serverresp, serversock, clientsock, dir_server_to_client); + tcptotal += timeofday() - tick; + http_log_activity (tick, 0, "sent serverbody to client"); /* Free up info from this request/response chat. */ http_header_free (clientreq); http_header_free (serverresp); + /* Overall activity reporting */ + http_log_activity (start, 0, "total processing (%g in TCP)", tcptotal); + /* Should we loop around? Go to copy-thru mode if either the * client or the server wants to stop. */ if (!client_persisting || !server_persisting) { diff --git a/src/lib/httpserversocket.c b/src/lib/httpserversocket.c @@ -1,5 +1,5 @@ /************************************************************************* - * This file is part of Crosroads 1.71, a load balancer and fail over + * This file is part of Crosroads 1.75, 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,11 @@ int http_serversocket (HttpHeader *m, int *is_continuation) { current_backend = i; if ( (sock = backend_connect ()) >= 0 ) { *is_continuation = 1; - if (!leave_proctitle) - setproctitle ("crossroads - Service %s: serving %s to %s", - activeservice->name, - client_ip, - activeservice->backend[current_backend].name); + set_program_title ("crossroads - Service %s: " + "serving %s to %s", + activeservice->name, + client_ip, + activeservice->backend[current_backend].name); return (sock); } } @@ -61,16 +61,15 @@ int http_serversocket (HttpHeader *m, int *is_continuation) { return (-2); } - msg ("Service %s: trying back end %d for new HTTP connection", - activeservice->name, current_backend); + msg ("Service %s: trying back end %s for new HTTP connection", + activeservice->name, activeservice->backend[current_backend].name); if ( (sock = backend_connect ()) >= 0 ) { servicereport->backendstate[current_backend].sessions++; *is_continuation = 0; - if (!leave_proctitle) - setproctitle ("Service %s: serving %s to %s", - activeservice->name, - client_ip, - activeservice->backend[current_backend].name); + set_program_title ("crossroads - 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.71, a load balancer and fail over + * This file is part of Crosroads 1.75, 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.71, a load balancer and fail over + * This file is part of Crosroads 1.75, 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.71, a load balancer and fail over + * This file is part of Crosroads 1.75, 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.71, a load balancer and fail over + * This file is part of Crosroads 1.75, 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.71, a load balancer and fail over + * This file is part of Crosroads 1.75, 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.71, a load balancer and fail over + * This file is part of Crosroads 1.75, 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.71, a load balancer and fail over + * This file is part of Crosroads 1.75, 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.71, a load balancer and fail over + * This file is part of Crosroads 1.75, 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.71, a load balancer and fail over + * This file is part of Crosroads 1.75, 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.71, a load balancer and fail over + * This file is part of Crosroads 1.75, 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.71, a load balancer and fail over + * This file is part of Crosroads 1.75, 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.71, a load balancer and fail over + * This file is part of Crosroads 1.75, 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.71, a load balancer and fail over + * This file is part of Crosroads 1.75, 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.71, a load balancer and fail over + * This file is part of Crosroads 1.75, 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,85 +288,96 @@ static void yy_fatal_error YY_PROTO(( yyconst char msg[] )); *yy_cp = '\0'; \ yy_c_buf_p = yy_cp; -#define YY_NUM_RULES 86 -#define YY_END_OF_BUFFER 87 -static yyconst short int yy_accept[513] = +#define YY_NUM_RULES 98 +#define YY_END_OF_BUFFER 99 +static yyconst short int yy_accept[616] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 83, 83, 84, 84, 87, 64, 62, 63, 64, 61, - 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, - 60, 60, 60, 60, 60, 60, 60, 60, 60, 64, - 73, 74, 72, 73, 73, 71, 68, 67, 68, 78, - 76, 77, 75, 82, 81, 79, 80, 79, 86, 83, - 84, 85, 62, 65, 0, 61, 60, 60, 60, 60, - 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, - 60, 60, 60, 60, 60, 60, 59, 60, 58, 60, - 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, - - 60, 11, 60, 60, 60, 60, 0, 0, 0, 0, - 69, 0, 70, 66, 75, 79, 80, 79, 83, 84, - 0, 3, 60, 60, 38, 60, 60, 60, 60, 60, - 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, - 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, - 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, - 60, 60, 60, 60, 60, 60, 60, 60, 60, 58, - 0, 0, 60, 60, 60, 60, 60, 60, 60, 60, - 60, 60, 60, 60, 60, 60, 60, 36, 60, 60, - 13, 60, 60, 60, 60, 40, 60, 60, 60, 60, - - 7, 6, 60, 60, 60, 60, 60, 60, 60, 60, - 60, 60, 60, 60, 60, 34, 60, 60, 60, 60, - 0, 0, 60, 60, 60, 60, 60, 60, 60, 60, - 60, 60, 60, 60, 60, 60, 60, 20, 60, 60, - 60, 60, 60, 60, 46, 60, 60, 60, 60, 60, - 60, 60, 60, 60, 60, 60, 60, 10, 60, 60, - 60, 60, 60, 60, 60, 0, 0, 60, 60, 60, - 60, 60, 60, 60, 5, 60, 60, 60, 60, 26, - 60, 60, 60, 60, 60, 60, 60, 60, 60, 45, - 60, 24, 60, 60, 60, 21, 60, 60, 60, 60, - - 8, 60, 60, 60, 60, 60, 60, 19, 0, 0, - 60, 60, 60, 60, 60, 60, 60, 9, 14, 60, - 60, 60, 27, 60, 60, 60, 60, 60, 60, 60, - 60, 60, 44, 15, 60, 60, 4, 60, 60, 37, - 60, 60, 60, 60, 60, 60, 16, 60, 2, 0, - 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, - 60, 60, 57, 55, 60, 60, 60, 60, 60, 60, - 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, - 1, 60, 60, 56, 54, 60, 60, 60, 60, 60, - 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, - - 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, - 60, 30, 60, 25, 60, 60, 60, 60, 60, 60, - 60, 60, 23, 60, 60, 60, 39, 60, 42, 60, - 60, 60, 60, 60, 60, 60, 60, 60, 60, 43, - 60, 60, 60, 60, 60, 60, 60, 60, 12, 31, - 60, 60, 60, 60, 60, 60, 60, 22, 60, 60, - 60, 60, 60, 60, 47, 60, 60, 60, 60, 60, - 28, 33, 60, 60, 60, 60, 60, 60, 60, 41, - 60, 60, 60, 60, 60, 60, 60, 18, 60, 60, - 60, 48, 51, 60, 60, 60, 29, 60, 60, 49, - - 52, 60, 60, 60, 35, 32, 60, 60, 17, 50, - 53, 0 + 0, 0, 95, 95, 96, 96, 99, 73, 71, 72, + 73, 70, 69, 69, 69, 69, 69, 69, 69, 69, + 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, + 69, 69, 73, 79, 78, 78, 85, 86, 84, 85, + 85, 83, 85, 77, 76, 77, 90, 88, 89, 87, + 94, 93, 91, 92, 91, 98, 95, 96, 97, 71, + 74, 0, 70, 69, 69, 69, 69, 69, 69, 69, + 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, + 69, 69, 69, 69, 69, 69, 68, 69, 67, 69, + + 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, + 69, 69, 69, 69, 19, 69, 69, 69, 69, 0, + 0, 0, 0, 81, 0, 82, 80, 75, 87, 91, + 92, 91, 95, 96, 0, 3, 69, 69, 46, 69, + 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, + 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, + 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, + 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, + 69, 69, 69, 69, 69, 69, 69, 69, 69, 67, + 0, 0, 69, 69, 69, 69, 69, 69, 69, 69, + + 69, 69, 69, 69, 69, 69, 69, 44, 69, 69, + 69, 21, 69, 69, 69, 69, 48, 69, 69, 69, + 69, 69, 69, 69, 69, 15, 14, 69, 69, 69, + 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, + 69, 69, 69, 42, 69, 69, 69, 69, 0, 0, + 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, + 69, 69, 69, 69, 69, 28, 69, 69, 69, 69, + 69, 69, 69, 69, 69, 69, 69, 55, 69, 69, + 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, + 69, 69, 69, 18, 69, 69, 69, 69, 69, 69, + + 69, 69, 0, 0, 69, 69, 69, 69, 69, 69, + 69, 13, 69, 69, 69, 69, 34, 69, 69, 69, + 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, + 69, 54, 69, 69, 32, 69, 69, 69, 29, 69, + 69, 69, 69, 16, 69, 69, 69, 69, 69, 69, + 69, 69, 69, 27, 0, 0, 69, 69, 69, 69, + 69, 69, 69, 17, 22, 69, 69, 69, 35, 69, + 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, + 69, 69, 69, 53, 4, 23, 69, 69, 12, 69, + 69, 45, 69, 69, 69, 69, 69, 69, 69, 69, + + 69, 24, 69, 2, 0, 69, 69, 69, 69, 69, + 69, 69, 69, 69, 69, 69, 69, 66, 64, 69, + 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, + 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, + 69, 69, 69, 1, 69, 69, 65, 63, 69, 69, + 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, + 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, + 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, + 69, 69, 38, 69, 33, 69, 69, 69, 69, 69, + 69, 69, 69, 69, 69, 69, 69, 69, 31, 69, + + 69, 69, 69, 69, 47, 69, 69, 50, 69, 69, + 69, 69, 69, 69, 69, 69, 69, 69, 7, 52, + 69, 69, 69, 69, 5, 8, 69, 69, 69, 69, + 69, 69, 69, 69, 69, 20, 39, 69, 69, 69, + 69, 69, 69, 69, 30, 69, 69, 69, 69, 69, + 69, 69, 69, 69, 69, 56, 69, 69, 69, 69, + 69, 69, 36, 41, 69, 69, 69, 51, 69, 69, + 69, 69, 69, 69, 69, 6, 49, 69, 69, 69, + 69, 69, 69, 69, 69, 26, 69, 69, 69, 9, + 10, 57, 60, 69, 69, 69, 37, 69, 69, 69, + + 58, 61, 69, 69, 69, 43, 69, 40, 69, 69, + 25, 11, 59, 62, 0 } ; static yyconst int yy_ec[256] = { 0, 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, + 1, 1, 4, 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, 4, 1, 5, 6, 1, 1, 1, 7, 1, - 1, 8, 1, 1, 9, 9, 10, 11, 11, 11, - 11, 11, 11, 11, 11, 11, 11, 9, 12, 9, - 1, 9, 1, 1, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 1, 9, 1, 1, 13, 1, 14, 15, 16, 17, - - 18, 19, 20, 21, 22, 13, 23, 24, 25, 26, - 27, 28, 13, 29, 30, 31, 32, 33, 34, 35, - 36, 37, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 5, 1, 6, 7, 1, 1, 1, 8, 1, + 1, 9, 1, 1, 10, 10, 11, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 10, 13, 10, + 1, 10, 1, 1, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 1, 15, 1, 1, 14, 1, 16, 17, 18, 19, + + 20, 21, 22, 23, 24, 14, 25, 26, 27, 28, + 29, 30, 14, 31, 32, 33, 34, 35, 36, 37, + 38, 39, 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, 1, @@ -383,288 +394,336 @@ static yyconst int yy_ec[256] = 1, 1, 1, 1, 1 } ; -static yyconst int yy_meta[38] = +static yyconst int yy_meta[40] = { 0, - 1, 1, 2, 1, 3, 1, 1, 1, 3, 3, - 4, 1, 4, 4, 4, 4, 4, 4, 4, 4, + 1, 1, 2, 1, 1, 3, 1, 1, 1, 3, + 3, 4, 1, 4, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 4 + 4, 4, 4, 4, 4, 4, 4, 4, 4 } ; -static yyconst short int yy_base[526] = +static yyconst short int yy_base[630] = { 0, - 0, 608, 35, 41, 46, 47, 55, 67, 79, 109, - 62, 74, 610, 609, 611, 615, 39, 615, 84, 599, - 0, 105, 110, 72, 108, 574, 594, 77, 593, 579, - 108, 578, 129, 124, 115, 70, 586, 585, 584, 146, - 615, 615, 615, 596, 593, 615, 615, 615, 589, 615, - 615, 615, 0, 615, 615, 93, 0, 98, 615, 99, - 0, 615, 102, 615, 595, 586, 0, 579, 571, 558, - 565, 578, 575, 564, 137, 571, 562, 143, 557, 552, - 560, 553, 559, 568, 550, 545, 0, 560, 147, 560, - 548, 550, 74, 543, 129, 148, 38, 545, 138, 545, - - 558, 0, 553, 541, 547, 538, 170, 549, 540, 560, - 615, 557, 615, 615, 0, 145, 0, 153, 174, 0, - 560, 615, 155, 535, 0, 543, 538, 536, 541, 155, - 525, 527, 533, 538, 527, 538, 523, 514, 521, 522, - 519, 528, 515, 527, 515, 526, 515, 526, 508, 509, - 506, 519, 506, 512, 507, 499, 164, 507, 507, 498, - 512, 500, 507, 507, 506, 490, 493, 506, 500, 0, - 500, 502, 493, 498, 481, 488, 489, 166, 481, 489, - 484, 480, 491, 470, 483, 487, 468, 0, 484, 488, - 0, 470, 471, 481, 480, 0, 470, 479, 473, 480, - - 0, 0, 466, 470, 458, 473, 171, 465, 470, 463, - 468, 467, 461, 451, 463, 0, 467, 466, 452, 457, - 455, 452, 453, 445, 454, 455, 457, 444, 442, 441, - 449, 440, 451, 446, 445, 440, 445, 0, 159, 429, - 430, 432, 428, 430, 0, 431, 425, 428, 434, 429, - 421, 420, 432, 425, 417, 418, 408, 0, 407, 422, - 419, 418, 423, 408, 406, 410, 403, 416, 400, 169, - 170, 417, 414, 410, 0, 403, 410, 396, 397, 0, - 399, 393, 399, 395, 405, 406, 405, 396, 391, 0, - 385, 0, 385, 388, 386, 0, 394, 393, 377, 375, - - 0, 180, 387, 391, 382, 389, 177, 0, 386, 386, - 376, 383, 376, 372, 374, 379, 372, 0, 0, 364, - 378, 371, 0, 361, 369, 372, 364, 367, 368, 362, - 359, 366, 0, 0, 363, 367, 0, 355, 362, 0, - 352, 347, 349, 352, 361, 347, 0, 342, 615, 354, - 340, 341, 351, 343, 345, 337, 347, 342, 332, 335, - 343, 333, 0, 0, 334, 339, 336, 326, 339, 332, - 331, 321, 322, 323, 318, 316, 320, 331, 313, 308, - 615, 322, 321, 0, 0, 323, 307, 311, 316, 311, - 307, 309, 307, 311, 318, 303, 299, 303, 302, 306, - - 305, 302, 296, 292, 302, 297, 294, 301, 300, 291, - 298, 0, 288, 0, 281, 282, 295, 295, 284, 291, - 286, 276, 0, 288, 287, 282, 0, 279, 0, 284, - 270, 286, 285, 267, 268, 270, 281, 272, 275, 0, - 275, 275, 263, 271, 274, 273, 268, 258, 0, 0, - 267, 266, 261, 260, 250, 255, 253, 0, 253, 245, - 249, 245, 256, 255, 0, 251, 252, 251, 250, 249, - 0, 0, 248, 247, 242, 233, 229, 243, 242, 0, - 230, 229, 243, 242, 228, 225, 226, 0, 238, 222, - 221, 0, 0, 232, 231, 215, 0, 220, 221, 0, - - 0, 226, 219, 166, 0, 0, 108, 96, 0, 0, - 0, 615, 201, 205, 209, 213, 217, 221, 68, 225, - 229, 231, 47, 235, 239 + 0, 726, 38, 42, 45, 58, 46, 53, 73, 86, + 99, 131, 65, 113, 729, 728, 730, 734, 52, 734, + 74, 717, 0, 94, 129, 36, 127, 691, 711, 59, + 97, 710, 696, 129, 695, 142, 146, 142, 91, 703, + 702, 701, 172, 734, 734, 734, 734, 734, 734, 714, + 711, 734, 90, 734, 734, 707, 734, 734, 734, 0, + 734, 734, 120, 0, 122, 734, 67, 0, 734, 173, + 734, 714, 704, 0, 696, 688, 675, 682, 695, 692, + 681, 163, 688, 679, 165, 674, 673, 668, 676, 669, + 675, 684, 666, 682, 675, 659, 0, 674, 166, 661, + + 673, 661, 663, 95, 656, 137, 172, 660, 160, 658, + 656, 173, 656, 669, 0, 664, 652, 658, 649, 192, + 660, 651, 672, 734, 669, 734, 734, 734, 0, 185, + 0, 195, 199, 0, 673, 734, 187, 646, 0, 654, + 649, 647, 652, 177, 636, 638, 644, 649, 638, 649, + 634, 625, 632, 643, 632, 629, 638, 625, 637, 625, + 619, 192, 635, 624, 635, 617, 625, 617, 614, 627, + 614, 620, 615, 607, 191, 615, 185, 610, 606, 620, + 620, 607, 614, 614, 613, 597, 600, 613, 607, 0, + 607, 609, 600, 605, 588, 595, 596, 192, 588, 596, + + 591, 587, 598, 577, 590, 594, 575, 0, 591, 595, + 594, 0, 576, 577, 587, 586, 572, 584, 585, 586, + 572, 581, 575, 582, 568, 0, 0, 567, 571, 559, + 574, 200, 566, 571, 564, 569, 568, 557, 566, 560, + 550, 549, 561, 0, 565, 564, 550, 555, 553, 550, + 551, 543, 552, 553, 555, 542, 540, 539, 547, 538, + 549, 544, 543, 538, 543, 0, 190, 527, 541, 527, + 529, 525, 531, 524, 520, 534, 523, 0, 524, 518, + 520, 520, 526, 521, 513, 512, 524, 517, 509, 510, + 500, 506, 498, 0, 497, 513, 511, 508, 507, 512, + + 497, 495, 499, 492, 505, 489, 198, 207, 506, 503, + 499, 0, 492, 499, 485, 486, 0, 488, 482, 488, + 484, 494, 488, 494, 493, 484, 480, 475, 481, 480, + 475, 0, 469, 469, 0, 468, 471, 469, 0, 477, + 476, 460, 458, 0, 466, 462, 208, 470, 467, 471, + 462, 469, 208, 0, 466, 466, 456, 463, 456, 452, + 454, 459, 452, 0, 0, 444, 458, 451, 0, 441, + 449, 452, 444, 447, 449, 447, 441, 438, 441, 435, + 428, 436, 441, 0, 0, 0, 438, 442, 0, 430, + 437, 0, 432, 426, 425, 420, 432, 421, 424, 433, + + 419, 0, 414, 734, 426, 412, 413, 423, 415, 417, + 409, 419, 414, 404, 407, 415, 405, 0, 0, 406, + 399, 410, 407, 397, 400, 409, 402, 401, 406, 399, + 398, 388, 389, 387, 387, 388, 383, 384, 380, 384, + 395, 377, 372, 734, 386, 385, 0, 0, 387, 371, + 375, 380, 375, 371, 373, 371, 366, 374, 381, 366, + 373, 374, 360, 359, 358, 362, 361, 365, 364, 354, + 352, 359, 353, 350, 348, 358, 353, 350, 357, 356, + 347, 354, 0, 344, 0, 337, 338, 351, 343, 350, + 339, 346, 339, 332, 325, 324, 337, 327, 0, 339, + + 338, 333, 339, 331, 0, 330, 327, 0, 332, 318, + 334, 333, 315, 316, 318, 329, 320, 323, 0, 0, + 323, 323, 311, 307, 0, 0, 309, 317, 320, 319, + 305, 309, 312, 292, 301, 0, 0, 310, 309, 304, + 303, 293, 298, 296, 0, 296, 288, 298, 286, 290, + 286, 297, 296, 286, 285, 0, 292, 289, 290, 289, + 288, 287, 0, 0, 286, 285, 280, 0, 279, 270, + 266, 280, 279, 266, 278, 0, 0, 265, 264, 278, + 277, 263, 260, 261, 256, 0, 272, 256, 255, 0, + 0, 0, 0, 260, 219, 203, 0, 208, 209, 208, + + 0, 0, 213, 210, 169, 0, 129, 0, 117, 66, + 0, 0, 0, 0, 734, 239, 243, 247, 251, 255, + 259, 263, 80, 267, 271, 273, 48, 277, 281 } ; -static yyconst short int yy_def[526] = +static yyconst short int yy_def[630] = { 0, - 512, 1, 513, 513, 514, 514, 515, 515, 516, 516, - 517, 517, 518, 518, 512, 512, 512, 512, 512, 512, - 519, 519, 519, 519, 519, 519, 519, 519, 519, 519, - 519, 519, 519, 519, 519, 519, 519, 519, 519, 512, - 512, 512, 512, 520, 521, 512, 512, 512, 512, 512, - 512, 512, 522, 512, 512, 512, 523, 523, 512, 512, - 524, 512, 512, 512, 525, 512, 519, 519, 519, 519, - 519, 519, 519, 519, 519, 519, 519, 519, 519, 519, - 519, 519, 519, 519, 519, 519, 519, 519, 519, 519, - 519, 519, 519, 519, 519, 519, 519, 519, 519, 519, - - 519, 519, 519, 519, 519, 519, 512, 512, 512, 520, - 512, 521, 512, 512, 522, 512, 523, 523, 512, 524, - 525, 512, 519, 519, 519, 519, 519, 519, 519, 519, - 519, 519, 519, 519, 519, 519, 519, 519, 519, 519, - 519, 519, 519, 519, 519, 519, 519, 519, 519, 519, - 519, 519, 519, 519, 519, 519, 519, 519, 519, 519, - 519, 519, 519, 519, 519, 519, 519, 519, 519, 519, - 512, 512, 519, 519, 519, 519, 519, 519, 519, 519, - 519, 519, 519, 519, 519, 519, 519, 519, 519, 519, - 519, 519, 519, 519, 519, 519, 519, 519, 519, 519, - - 519, 519, 519, 519, 519, 519, 519, 519, 519, 519, - 519, 519, 519, 519, 519, 519, 519, 519, 519, 519, - 512, 512, 519, 519, 519, 519, 519, 519, 519, 519, - 519, 519, 519, 519, 519, 519, 519, 519, 519, 519, - 519, 519, 519, 519, 519, 519, 519, 519, 519, 519, - 519, 519, 519, 519, 519, 519, 519, 519, 519, 519, - 519, 519, 519, 519, 519, 512, 512, 519, 519, 519, - 519, 519, 519, 519, 519, 519, 519, 519, 519, 519, - 519, 519, 519, 519, 519, 519, 519, 519, 519, 519, - 519, 519, 519, 519, 519, 519, 519, 519, 519, 519, - - 519, 519, 519, 519, 519, 519, 519, 519, 512, 512, - 519, 519, 519, 519, 519, 519, 519, 519, 519, 519, - 519, 519, 519, 519, 519, 519, 519, 519, 519, 519, - 519, 519, 519, 519, 519, 519, 519, 519, 519, 519, - 519, 519, 519, 519, 519, 519, 519, 519, 512, 512, - 519, 519, 519, 519, 519, 519, 519, 519, 519, 519, - 519, 519, 519, 519, 519, 519, 519, 519, 519, 519, - 519, 519, 519, 519, 519, 519, 519, 519, 519, 519, - 512, 519, 519, 519, 519, 519, 519, 519, 519, 519, - 519, 519, 519, 519, 519, 519, 519, 519, 519, 519, - - 519, 519, 519, 519, 519, 519, 519, 519, 519, 519, - 519, 519, 519, 519, 519, 519, 519, 519, 519, 519, - 519, 519, 519, 519, 519, 519, 519, 519, 519, 519, - 519, 519, 519, 519, 519, 519, 519, 519, 519, 519, - 519, 519, 519, 519, 519, 519, 519, 519, 519, 519, - 519, 519, 519, 519, 519, 519, 519, 519, 519, 519, - 519, 519, 519, 519, 519, 519, 519, 519, 519, 519, - 519, 519, 519, 519, 519, 519, 519, 519, 519, 519, - 519, 519, 519, 519, 519, 519, 519, 519, 519, 519, - 519, 519, 519, 519, 519, 519, 519, 519, 519, 519, - - 519, 519, 519, 519, 519, 519, 519, 519, 519, 519, - 519, 0, 512, 512, 512, 512, 512, 512, 512, 512, - 512, 512, 512, 512, 512 + 615, 1, 616, 616, 617, 617, 618, 618, 619, 619, + 620, 620, 621, 621, 622, 622, 615, 615, 615, 615, + 615, 615, 623, 623, 623, 623, 623, 623, 623, 623, + 623, 623, 623, 623, 623, 623, 623, 623, 623, 623, + 623, 623, 615, 615, 615, 615, 615, 615, 615, 624, + 625, 615, 615, 615, 615, 615, 615, 615, 615, 626, + 615, 615, 615, 627, 627, 615, 615, 628, 615, 615, + 615, 629, 615, 623, 623, 623, 623, 623, 623, 623, + 623, 623, 623, 623, 623, 623, 623, 623, 623, 623, + 623, 623, 623, 623, 623, 623, 623, 623, 623, 623, + + 623, 623, 623, 623, 623, 623, 623, 623, 623, 623, + 623, 623, 623, 623, 623, 623, 623, 623, 623, 615, + 615, 615, 624, 615, 625, 615, 615, 615, 626, 615, + 627, 627, 615, 628, 629, 615, 623, 623, 623, 623, + 623, 623, 623, 623, 623, 623, 623, 623, 623, 623, + 623, 623, 623, 623, 623, 623, 623, 623, 623, 623, + 623, 623, 623, 623, 623, 623, 623, 623, 623, 623, + 623, 623, 623, 623, 623, 623, 623, 623, 623, 623, + 623, 623, 623, 623, 623, 623, 623, 623, 623, 623, + 615, 615, 623, 623, 623, 623, 623, 623, 623, 623, + + 623, 623, 623, 623, 623, 623, 623, 623, 623, 623, + 623, 623, 623, 623, 623, 623, 623, 623, 623, 623, + 623, 623, 623, 623, 623, 623, 623, 623, 623, 623, + 623, 623, 623, 623, 623, 623, 623, 623, 623, 623, + 623, 623, 623, 623, 623, 623, 623, 623, 615, 615, + 623, 623, 623, 623, 623, 623, 623, 623, 623, 623, + 623, 623, 623, 623, 623, 623, 623, 623, 623, 623, + 623, 623, 623, 623, 623, 623, 623, 623, 623, 623, + 623, 623, 623, 623, 623, 623, 623, 623, 623, 623, + 623, 623, 623, 623, 623, 623, 623, 623, 623, 623, + + 623, 623, 615, 615, 623, 623, 623, 623, 623, 623, + 623, 623, 623, 623, 623, 623, 623, 623, 623, 623, + 623, 623, 623, 623, 623, 623, 623, 623, 623, 623, + 623, 623, 623, 623, 623, 623, 623, 623, 623, 623, + 623, 623, 623, 623, 623, 623, 623, 623, 623, 623, + 623, 623, 623, 623, 615, 615, 623, 623, 623, 623, + 623, 623, 623, 623, 623, 623, 623, 623, 623, 623, + 623, 623, 623, 623, 623, 623, 623, 623, 623, 623, + 623, 623, 623, 623, 623, 623, 623, 623, 623, 623, + 623, 623, 623, 623, 623, 623, 623, 623, 623, 623, + + 623, 623, 623, 615, 615, 623, 623, 623, 623, 623, + 623, 623, 623, 623, 623, 623, 623, 623, 623, 623, + 623, 623, 623, 623, 623, 623, 623, 623, 623, 623, + 623, 623, 623, 623, 623, 623, 623, 623, 623, 623, + 623, 623, 623, 615, 623, 623, 623, 623, 623, 623, + 623, 623, 623, 623, 623, 623, 623, 623, 623, 623, + 623, 623, 623, 623, 623, 623, 623, 623, 623, 623, + 623, 623, 623, 623, 623, 623, 623, 623, 623, 623, + 623, 623, 623, 623, 623, 623, 623, 623, 623, 623, + 623, 623, 623, 623, 623, 623, 623, 623, 623, 623, + + 623, 623, 623, 623, 623, 623, 623, 623, 623, 623, + 623, 623, 623, 623, 623, 623, 623, 623, 623, 623, + 623, 623, 623, 623, 623, 623, 623, 623, 623, 623, + 623, 623, 623, 623, 623, 623, 623, 623, 623, 623, + 623, 623, 623, 623, 623, 623, 623, 623, 623, 623, + 623, 623, 623, 623, 623, 623, 623, 623, 623, 623, + 623, 623, 623, 623, 623, 623, 623, 623, 623, 623, + 623, 623, 623, 623, 623, 623, 623, 623, 623, 623, + 623, 623, 623, 623, 623, 623, 623, 623, 623, 623, + 623, 623, 623, 623, 623, 623, 623, 623, 623, 623, + + 623, 623, 623, 623, 623, 623, 623, 623, 623, 623, + 623, 623, 623, 623, 0, 615, 615, 615, 615, 615, + 615, 615, 615, 615, 615, 615, 615, 615, 615 } ; -static yyconst short int yy_nxt[653] = +static yyconst short int yy_nxt[774] = { 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, - 117, 160, 46, 49, 49, 50, 51, 52, 51, 161, - 50, 50, 50, 60, 55, 60, 50, 50, 51, 52, - 51, 67, 50, 50, 50, 60, 55, 60, 50, 54, - 54, 55, 56, 54, 54, 54, 54, 54, 54, 54, - 54, 64, 76, 65, 84, 101, 116, 102, 77, 103, - - 119, 116, 119, 63, 153, 63, 154, 85, 58, 54, - 54, 55, 56, 54, 54, 54, 54, 54, 54, 54, - 54, 68, 116, 73, 511, 78, 88, 118, 69, 79, - 70, 74, 71, 89, 80, 98, 510, 72, 58, 81, - 90, 95, 92, 99, 96, 75, 93, 107, 116, 107, - 100, 163, 130, 131, 97, 94, 116, 156, 136, 157, - 137, 158, 108, 132, 147, 148, 133, 109, 138, 164, - 173, 107, 159, 107, 116, 119, 149, 119, 180, 208, - 283, 181, 118, 228, 174, 315, 108, 284, 252, 229, - 313, 109, 253, 209, 347, 341, 509, 314, 348, 316, - - 342, 41, 41, 41, 41, 47, 47, 47, 47, 53, - 53, 53, 53, 57, 57, 57, 57, 59, 59, 59, - 59, 61, 61, 61, 61, 110, 110, 110, 110, 112, - 112, 112, 112, 115, 115, 120, 508, 120, 120, 121, - 121, 121, 121, 507, 506, 505, 504, 503, 502, 501, - 500, 499, 498, 497, 496, 495, 494, 493, 492, 491, - 490, 489, 488, 487, 486, 485, 484, 483, 482, 481, - 480, 479, 478, 477, 476, 475, 474, 473, 472, 471, - 470, 469, 468, 467, 466, 465, 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, 347, 407, 406, 405, 404, 403, 402, - 401, 400, 399, 398, 397, 396, 395, 394, 393, 392, - 391, 390, 389, 388, 102, 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, - 362, 361, 360, 359, 358, 357, 356, 355, 354, 353, - - 352, 351, 350, 349, 346, 345, 344, 343, 340, 339, - 338, 337, 336, 335, 334, 333, 332, 331, 330, 329, - 328, 327, 326, 325, 324, 323, 322, 321, 320, 319, - 318, 317, 312, 311, 310, 309, 308, 307, 306, 305, - 304, 303, 302, 301, 300, 299, 298, 297, 296, 295, - 294, 293, 292, 291, 290, 289, 288, 287, 286, 285, - 282, 281, 280, 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, 254, 251, - 250, 249, 248, 247, 246, 245, 244, 243, 87, 242, - - 241, 240, 239, 238, 237, 236, 235, 234, 233, 232, - 231, 230, 227, 226, 225, 224, 223, 222, 221, 220, - 219, 218, 217, 216, 170, 215, 214, 213, 212, 211, - 210, 207, 206, 205, 204, 203, 202, 201, 200, 199, - 198, 197, 196, 195, 194, 193, 192, 191, 190, 189, - 188, 187, 186, 185, 184, 183, 182, 179, 178, 177, - 176, 175, 122, 113, 111, 172, 171, 170, 169, 168, - 167, 166, 165, 162, 155, 152, 151, 150, 87, 146, - 145, 144, 143, 142, 141, 140, 139, 135, 134, 129, - 128, 127, 126, 125, 124, 123, 66, 122, 114, 113, - - 111, 106, 105, 104, 91, 87, 86, 83, 82, 66, - 512, 62, 62, 40, 15, 512, 512, 512, 512, 512, - 512, 512, 512, 512, 512, 512, 512, 512, 512, 512, - 512, 512, 512, 512, 512, 512, 512, 512, 512, 512, - 512, 512, 512, 512, 512, 512, 512, 512, 512, 512, - 512, 512 + 18, 19, 20, 18, 19, 18, 18, 18, 18, 18, + 21, 22, 18, 23, 18, 24, 25, 26, 27, 28, + 29, 23, 30, 23, 23, 31, 32, 33, 34, 35, + 36, 37, 38, 39, 40, 41, 23, 42, 23, 45, + 46, 45, 45, 45, 46, 45, 45, 48, 55, 49, + 50, 131, 51, 70, 56, 55, 70, 52, 83, 53, + 48, 56, 49, 50, 84, 51, 67, 62, 133, 67, + 52, 133, 53, 57, 58, 59, 57, 58, 92, 57, + 57, 57, 71, 74, 72, 57, 57, 58, 59, 57, + 58, 93, 57, 57, 57, 127, 614, 127, 57, 61, + + 61, 62, 61, 63, 61, 61, 61, 61, 61, 61, + 61, 61, 75, 61, 67, 62, 94, 67, 114, 76, + 115, 77, 116, 78, 130, 95, 130, 171, 79, 172, + 65, 61, 61, 62, 61, 63, 61, 61, 61, 61, + 61, 61, 61, 61, 80, 61, 85, 613, 612, 98, + 86, 130, 81, 132, 87, 88, 99, 103, 100, 110, + 89, 104, 65, 101, 111, 106, 82, 174, 107, 175, + 105, 108, 112, 120, 70, 179, 120, 70, 109, 113, + 144, 145, 150, 180, 151, 164, 165, 176, 183, 130, + 121, 146, 152, 120, 147, 122, 120, 166, 177, 130, + + 133, 611, 200, 133, 193, 201, 184, 219, 233, 236, + 121, 256, 220, 320, 237, 122, 130, 257, 194, 286, + 321, 359, 234, 287, 361, 395, 132, 402, 360, 610, + 396, 403, 609, 608, 607, 606, 605, 604, 362, 44, + 44, 44, 44, 47, 47, 47, 47, 54, 54, 54, + 54, 60, 60, 60, 60, 64, 64, 64, 64, 66, + 66, 66, 66, 68, 68, 68, 68, 123, 123, 123, + 123, 125, 125, 125, 125, 129, 129, 134, 603, 134, + 134, 135, 135, 135, 135, 602, 601, 600, 599, 598, + 597, 596, 595, 594, 593, 592, 591, 590, 589, 588, + + 587, 586, 585, 584, 583, 582, 581, 580, 579, 578, + 577, 576, 575, 574, 573, 572, 571, 570, 569, 568, + 567, 566, 565, 564, 563, 562, 561, 560, 559, 558, + 557, 556, 555, 554, 553, 552, 551, 550, 549, 548, + 547, 546, 545, 544, 543, 542, 541, 540, 539, 538, + 537, 536, 535, 534, 533, 532, 531, 530, 529, 528, + 527, 526, 525, 524, 523, 522, 521, 520, 519, 518, + 517, 516, 515, 514, 513, 512, 511, 510, 509, 508, + 507, 506, 505, 504, 503, 502, 501, 500, 499, 498, + 497, 496, 495, 494, 493, 492, 491, 490, 489, 488, + + 487, 486, 485, 484, 483, 482, 481, 480, 479, 402, + 478, 477, 476, 475, 474, 473, 472, 471, 470, 469, + 468, 467, 466, 465, 464, 463, 462, 461, 460, 459, + 458, 457, 456, 455, 454, 453, 452, 451, 115, 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, 401, 400, 399, 398, + 397, 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, 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, + 319, 318, 317, 316, 315, 314, 313, 312, 311, 310, + 309, 308, 307, 306, 305, 304, 303, 302, 301, 300, + 299, 298, 297, 296, 295, 294, 293, 292, 291, 290, + 289, 288, 285, 284, 283, 282, 281, 280, 279, 278, + + 277, 276, 275, 274, 273, 272, 97, 271, 270, 269, + 268, 267, 266, 265, 264, 263, 262, 261, 260, 259, + 258, 255, 254, 253, 252, 251, 250, 249, 248, 247, + 246, 245, 244, 190, 243, 242, 241, 240, 239, 238, + 235, 232, 231, 230, 229, 228, 227, 226, 225, 224, + 223, 222, 221, 218, 217, 216, 215, 214, 213, 212, + 211, 210, 209, 208, 207, 206, 205, 204, 203, 202, + 199, 198, 197, 196, 195, 136, 126, 124, 192, 191, + 190, 189, 188, 187, 186, 185, 182, 181, 178, 173, + 170, 169, 168, 167, 97, 163, 162, 161, 160, 159, + + 158, 157, 156, 155, 154, 153, 149, 148, 143, 142, + 141, 140, 139, 138, 137, 73, 136, 128, 126, 124, + 119, 118, 117, 102, 97, 96, 91, 90, 73, 615, + 69, 69, 43, 17, 615, 615, 615, 615, 615, 615, + 615, 615, 615, 615, 615, 615, 615, 615, 615, 615, + 615, 615, 615, 615, 615, 615, 615, 615, 615, 615, + 615, 615, 615, 615, 615, 615, 615, 615, 615, 615, + 615, 615, 615 } ; -static yyconst short int yy_chk[653] = +static yyconst short int yy_chk[774] = { 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, - 523, 97, 4, 5, 6, 7, 7, 7, 7, 97, - 7, 7, 7, 11, 11, 11, 7, 8, 8, 8, - 8, 519, 8, 8, 8, 12, 12, 12, 8, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 19, 24, 19, 28, 36, 56, 36, 24, 36, - - 60, 58, 60, 63, 93, 63, 93, 28, 9, 10, - 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, - 10, 22, 56, 23, 508, 25, 31, 58, 22, 25, - 22, 23, 22, 31, 25, 35, 507, 22, 10, 25, - 31, 34, 33, 35, 34, 23, 33, 40, 116, 40, - 35, 99, 75, 75, 34, 33, 118, 95, 78, 95, - 78, 96, 40, 75, 89, 89, 75, 40, 78, 99, - 123, 107, 96, 107, 116, 119, 89, 119, 130, 157, - 239, 130, 118, 178, 123, 271, 107, 239, 207, 178, - 270, 107, 207, 157, 307, 302, 504, 270, 307, 271, - - 302, 513, 513, 513, 513, 514, 514, 514, 514, 515, - 515, 515, 515, 516, 516, 516, 516, 517, 517, 517, - 517, 518, 518, 518, 518, 520, 520, 520, 520, 521, - 521, 521, 521, 522, 522, 524, 503, 524, 524, 525, - 525, 525, 525, 502, 499, 498, 496, 495, 494, 491, - 490, 489, 487, 486, 485, 484, 483, 482, 481, 479, - 478, 477, 476, 475, 474, 473, 470, 469, 468, 467, - 466, 464, 463, 462, 461, 460, 459, 457, 456, 455, - 454, 453, 452, 451, 448, 447, 446, 445, 444, 443, - 442, 441, 439, 438, 437, 436, 435, 434, 433, 432, - - 431, 430, 428, 426, 425, 424, 422, 421, 420, 419, - 418, 417, 416, 415, 413, 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, 383, 382, 380, 379, 378, 377, 376, 375, 374, - 373, 372, 371, 370, 369, 368, 367, 366, 365, 362, - 361, 360, 359, 358, 357, 356, 355, 354, 353, 352, - 351, 350, 348, 346, 345, 344, 343, 342, 341, 339, - 338, 336, 335, 332, 331, 330, 329, 328, 327, 326, - 325, 324, 322, 321, 320, 317, 316, 315, 314, 313, - - 312, 311, 310, 309, 306, 305, 304, 303, 300, 299, - 298, 297, 295, 294, 293, 291, 289, 288, 287, 286, - 285, 284, 283, 282, 281, 279, 278, 277, 276, 274, - 273, 272, 269, 268, 267, 266, 265, 264, 263, 262, - 261, 260, 259, 257, 256, 255, 254, 253, 252, 251, - 250, 249, 248, 247, 246, 244, 243, 242, 241, 240, - 237, 236, 235, 234, 233, 232, 231, 230, 229, 228, - 227, 226, 225, 224, 223, 222, 221, 220, 219, 218, - 217, 215, 214, 213, 212, 211, 210, 209, 208, 206, - 205, 204, 203, 200, 199, 198, 197, 195, 194, 193, - - 192, 190, 189, 187, 186, 185, 184, 183, 182, 181, - 180, 179, 177, 176, 175, 174, 173, 172, 171, 169, - 168, 167, 166, 165, 164, 163, 162, 161, 160, 159, - 158, 156, 155, 154, 153, 152, 151, 150, 149, 148, - 147, 146, 145, 144, 143, 142, 141, 140, 139, 138, - 137, 136, 135, 134, 133, 132, 131, 129, 128, 127, - 126, 124, 121, 112, 110, 109, 108, 106, 105, 104, - 103, 101, 100, 98, 94, 92, 91, 90, 88, 86, - 85, 84, 83, 82, 81, 80, 79, 77, 76, 74, - 73, 72, 71, 70, 69, 68, 66, 65, 49, 45, - - 44, 39, 38, 37, 32, 30, 29, 27, 26, 20, - 15, 14, 13, 2, 512, 512, 512, 512, 512, 512, - 512, 512, 512, 512, 512, 512, 512, 512, 512, 512, - 512, 512, 512, 512, 512, 512, 512, 512, 512, 512, - 512, 512, 512, 512, 512, 512, 512, 512, 512, 512, - 512, 512 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, + 3, 3, 3, 4, 4, 4, 4, 5, 7, 5, + 5, 627, 5, 19, 7, 8, 19, 5, 26, 5, + 6, 8, 6, 6, 26, 6, 13, 13, 67, 13, + 6, 67, 6, 9, 9, 9, 9, 9, 30, 9, + 9, 9, 21, 623, 21, 9, 10, 10, 10, 10, + 10, 30, 10, 10, 10, 53, 610, 53, 10, 11, + + 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 24, 11, 14, 14, 31, 14, 39, 24, + 39, 24, 39, 24, 63, 31, 65, 104, 24, 104, + 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 25, 12, 27, 609, 607, 34, + 27, 63, 25, 65, 27, 27, 34, 36, 34, 38, + 27, 36, 12, 34, 38, 37, 25, 106, 37, 106, + 36, 37, 38, 43, 70, 109, 43, 70, 37, 38, + 82, 82, 85, 109, 85, 99, 99, 107, 112, 130, + 43, 82, 85, 120, 82, 43, 120, 99, 107, 132, + + 133, 605, 144, 133, 137, 144, 112, 162, 175, 177, + 120, 198, 162, 267, 177, 120, 130, 198, 137, 232, + 267, 307, 175, 232, 308, 347, 132, 353, 307, 604, + 347, 353, 603, 600, 599, 598, 596, 595, 308, 616, + 616, 616, 616, 617, 617, 617, 617, 618, 618, 618, + 618, 619, 619, 619, 619, 620, 620, 620, 620, 621, + 621, 621, 621, 622, 622, 622, 622, 624, 624, 624, + 624, 625, 625, 625, 625, 626, 626, 628, 594, 628, + 628, 629, 629, 629, 629, 589, 588, 587, 585, 584, + 583, 582, 581, 580, 579, 578, 575, 574, 573, 572, + + 571, 570, 569, 567, 566, 565, 562, 561, 560, 559, + 558, 557, 555, 554, 553, 552, 551, 550, 549, 548, + 547, 546, 544, 543, 542, 541, 540, 539, 538, 535, + 534, 533, 532, 531, 530, 529, 528, 527, 524, 523, + 522, 521, 518, 517, 516, 515, 514, 513, 512, 511, + 510, 509, 507, 506, 504, 503, 502, 501, 500, 498, + 497, 496, 495, 494, 493, 492, 491, 490, 489, 488, + 487, 486, 484, 482, 481, 480, 479, 478, 477, 476, + 475, 474, 473, 472, 471, 470, 469, 468, 467, 466, + 465, 464, 463, 462, 461, 460, 459, 458, 457, 456, + + 455, 454, 453, 452, 451, 450, 449, 446, 445, 443, + 442, 441, 440, 439, 438, 437, 436, 435, 434, 433, + 432, 431, 430, 429, 428, 427, 426, 425, 424, 423, + 422, 421, 420, 417, 416, 415, 414, 413, 412, 411, + 410, 409, 408, 407, 406, 405, 403, 401, 400, 399, + 398, 397, 396, 395, 394, 393, 391, 390, 388, 387, + 383, 382, 381, 380, 379, 378, 377, 376, 375, 374, + 373, 372, 371, 370, 368, 367, 366, 363, 362, 361, + 360, 359, 358, 357, 356, 355, 352, 351, 350, 349, + 348, 346, 345, 343, 342, 341, 340, 338, 337, 336, + + 334, 333, 331, 330, 329, 328, 327, 326, 325, 324, + 323, 322, 321, 320, 319, 318, 316, 315, 314, 313, + 311, 310, 309, 306, 305, 304, 303, 302, 301, 300, + 299, 298, 297, 296, 295, 293, 292, 291, 290, 289, + 288, 287, 286, 285, 284, 283, 282, 281, 280, 279, + 277, 276, 275, 274, 273, 272, 271, 270, 269, 268, + 265, 264, 263, 262, 261, 260, 259, 258, 257, 256, + 255, 254, 253, 252, 251, 250, 249, 248, 247, 246, + 245, 243, 242, 241, 240, 239, 238, 237, 236, 235, + 234, 233, 231, 230, 229, 228, 225, 224, 223, 222, + + 221, 220, 219, 218, 217, 216, 215, 214, 213, 211, + 210, 209, 207, 206, 205, 204, 203, 202, 201, 200, + 199, 197, 196, 195, 194, 193, 192, 191, 189, 188, + 187, 186, 185, 184, 183, 182, 181, 180, 179, 178, + 176, 174, 173, 172, 171, 170, 169, 168, 167, 166, + 165, 164, 163, 161, 160, 159, 158, 157, 156, 155, + 154, 153, 152, 151, 150, 149, 148, 147, 146, 145, + 143, 142, 141, 140, 138, 135, 125, 123, 122, 121, + 119, 118, 117, 116, 114, 113, 111, 110, 108, 105, + 103, 102, 101, 100, 98, 96, 95, 94, 93, 92, + + 91, 90, 89, 88, 87, 86, 84, 83, 81, 80, + 79, 78, 77, 76, 75, 73, 72, 56, 51, 50, + 42, 41, 40, 35, 33, 32, 29, 28, 22, 17, + 16, 15, 2, 615, 615, 615, 615, 615, 615, 615, + 615, 615, 615, 615, 615, 615, 615, 615, 615, 615, + 615, 615, 615, 615, 615, 615, 615, 615, 615, 615, + 615, 615, 615, 615, 615, 615, 615, 615, 615, 615, + 615, 615, 615 } ; static yy_state_type yy_last_accepting_state; @@ -688,27 +747,28 @@ char *yytext; #define YY_INPUT(buf,res,max) (res) = parser_input( (buf), (max) ) #define yywrap parser_close +/* Globals */ +static int i; + /* Lexer debugging related */ -/* #define LEXER_DEBUG */ -#ifdef LEXER_DEBUG - static void lmsg (char const *x) { - printf ("L: %s\n", x); - } - static void llmsg (char const *x, char const *y) { - printf ("L: %s %s\n", x, y); +static void lmsg (char const *fmt, ...) { + va_list args; + + if (parser_debug) { + va_start (args, fmt); + printf ("LEXER: "); + vprintf (fmt, args); } -#else -# define lmsg(x) -# define llmsg(x,y) -#endif +} #define stringstate 1 -#define commentstate 2 -#define includestate 3 -#define definestate 4 -#define defineredef 5 -#define definesym 6 +#define instr 2 +#define commentstate 3 +#define includestate 4 +#define definestate 5 +#define defineredef 6 +#define definesym 7 -#line 707 "lexer.c" +#line 767 "lexer.c" /* Macros after this point can all be overridden by user definitions in * section 1. @@ -865,7 +925,7 @@ YY_DECL #line 27 "lexer.l" -#line 864 "lexer.c" +#line 924 "lexer.c" if ( yy_init ) { @@ -917,13 +977,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 >= 513 ) + if ( yy_current_state >= 616 ) 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] != 615 ); + while ( yy_base[yy_current_state] != 734 ); yy_find_action: yy_act = yy_accept[yy_current_state]; @@ -953,7 +1013,7 @@ case 1: YY_RULE_SETUP #line 29 "lexer.l" { - lmsg ("include starts"); + lmsg ("include starts\n"); BEGIN (includestate); } YY_BREAK @@ -961,7 +1021,7 @@ case 2: YY_RULE_SETUP #line 35 "lexer.l" { - lmsg ("define starts"); + lmsg ("define starts\n"); BEGIN (definestate); } YY_BREAK @@ -969,7 +1029,7 @@ case 3: YY_RULE_SETUP #line 40 "lexer.l" { - lmsg ("comment"); + lmsg ("comment\n"); yylineno++; } YY_BREAK @@ -977,339 +1037,414 @@ case 4: YY_RULE_SETUP #line 45 "lexer.l" { - lmsg ("service"); - return (SERVICE); + lmsg ("options\n"); + return (OPTIONS); } YY_BREAK case 5: YY_RULE_SETUP #line 50 "lexer.l" { - lmsg ("bindto"); - BEGIN (stringstate); - free (laststring); - laststring = 0; - return (BINDTO); + lmsg ("logactivity\n"); + return (LOGACTIVITY); } YY_BREAK case 6: YY_RULE_SETUP -#line 58 "lexer.l" +#line 55 "lexer.l" { - lmsg ("port"); - return (PORT); + lmsg ("tcpbuffersize\n"); + return (TCPBUFFERSIZE); } YY_BREAK case 7: YY_RULE_SETUP -#line 63 "lexer.l" +#line 60 "lexer.l" { - lmsg ("over"); - return (OVER); + lmsg ("dnscachettl\n"); + return (DNSCACHETTL); } YY_BREAK case 8: YY_RULE_SETUP -#line 68 "lexer.l" +#line 65 "lexer.l" { - lmsg ("shmkey"); - return (SHMKEY); + lmsg ("logfacility\n"); + return (LOGFACILITY); } YY_BREAK case 9: YY_RULE_SETUP -#line 73 "lexer.l" +#line 70 "lexer.l" { - lmsg ("backend"); - return (BACKEND); + lmsg ("shmpermissions\n"); + return (SHMPERMISSIONS); } YY_BREAK case 10: YY_RULE_SETUP -#line 78 "lexer.l" +#line 75 "lexer.l" { - lmsg ("state"); - return (STATE); + lmsg ("sloppyportbind\n"); + return (SLOPPYPORTBIND); } YY_BREAK case 11: YY_RULE_SETUP -#line 83 "lexer.l" +#line 80 "lexer.l" { - lmsg ("available"); - return (AVAILABLE); + lmsg ("leaveprocesstitle\n"); + return (LEAVEPROCESSTITLE); } YY_BREAK case 12: YY_RULE_SETUP -#line 88 "lexer.l" +#line 85 "lexer.l" { - lmsg ("unavailable"); - return (UNAVAILABLE); + lmsg ("service\n"); + return (SERVICE); } YY_BREAK case 13: YY_RULE_SETUP -#line 93 "lexer.l" +#line 90 "lexer.l" { - lmsg ("down"); - return (DOWN); + lmsg ("bindto\n"); + BEGIN (stringstate); + free (laststring); + laststring = 0; + return (BINDTO); } YY_BREAK case 14: YY_RULE_SETUP #line 98 "lexer.l" { - lmsg ("backlog"); - return (BACKLOG); + lmsg ("port\n"); + return (PORT); } YY_BREAK case 15: YY_RULE_SETUP #line 103 "lexer.l" { - lmsg ("retries"); - return (RETRIES); + lmsg ("over\n"); + return (OVER); } YY_BREAK case 16: YY_RULE_SETUP #line 108 "lexer.l" { - lmsg ("verbosity"); - return (VERBOSITY); + lmsg ("shmkey\n"); + return (SHMKEY); } YY_BREAK case 17: YY_RULE_SETUP #line 113 "lexer.l" { - lmsg ("connectiontimeout"); - return (CONNECTIONTIMEOUT); + lmsg ("backend\n"); + return (BACKEND); } YY_BREAK case 18: YY_RULE_SETUP #line 118 "lexer.l" { - lmsg ("maxconnections"); - return (MAXCONNECTIONS); + lmsg ("state\n"); + return (STATE); } YY_BREAK case 19: YY_RULE_SETUP #line 123 "lexer.l" { - lmsg ("weight"); - return (WEIGHT); + lmsg ("available\n"); + return (AVAILABLE); } YY_BREAK case 20: YY_RULE_SETUP #line 128 "lexer.l" { - lmsg ("decay"); - return (DECAY); + lmsg ("unavailable\n"); + return (UNAVAILABLE); } YY_BREAK case 21: YY_RULE_SETUP #line 133 "lexer.l" { - lmsg ("server"); + lmsg ("down\n"); + return (DOWN); +} + YY_BREAK +case 22: +YY_RULE_SETUP +#line 138 "lexer.l" +{ + lmsg ("backlog\n"); + return (BACKLOG); +} + YY_BREAK +case 23: +YY_RULE_SETUP +#line 143 "lexer.l" +{ + lmsg ("retries\n"); + return (RETRIES); +} + YY_BREAK +case 24: +YY_RULE_SETUP +#line 148 "lexer.l" +{ + lmsg ("verbosity\n"); + return (VERBOSITY); +} + YY_BREAK +case 25: +YY_RULE_SETUP +#line 153 "lexer.l" +{ + lmsg ("connectiontimeout\n"); + return (CONNECTIONTIMEOUT); +} + YY_BREAK +case 26: +YY_RULE_SETUP +#line 158 "lexer.l" +{ + lmsg ("maxconnections\n"); + return (MAXCONNECTIONS); +} + YY_BREAK +case 27: +YY_RULE_SETUP +#line 163 "lexer.l" +{ + lmsg ("weight\n"); + return (WEIGHT); +} + YY_BREAK +case 28: +YY_RULE_SETUP +#line 168 "lexer.l" +{ + lmsg ("decay\n"); + return (DECAY); +} + YY_BREAK +case 29: +YY_RULE_SETUP +#line 173 "lexer.l" +{ + lmsg ("server\n"); BEGIN (stringstate); free (laststring); laststring = 0; return (SERVER); } YY_BREAK -case 22: +case 30: YY_RULE_SETUP -#line 141 "lexer.l" +#line 181 "lexer.l" { - lmsg ("dispatchmode"); + lmsg ("dispatchmode\n"); return (DISPATCHMODE); } YY_BREAK -case 23: +case 31: YY_RULE_SETUP -#line 146 "lexer.l" +#line 186 "lexer.l" { - lmsg ("roundrobin"); + lmsg ("roundrobin\n"); return (ROUNDROBIN); } YY_BREAK -case 24: +case 32: YY_RULE_SETUP -#line 151 "lexer.l" +#line 191 "lexer.l" { - lmsg ("random"); + lmsg ("random\n"); return (RANDOM); } YY_BREAK -case 25: +case 33: YY_RULE_SETUP -#line 156 "lexer.l" +#line 196 "lexer.l" { - lmsg ("byduration"); + lmsg ("byduration\n"); return (BYDURATION); } YY_BREAK -case 26: +case 34: YY_RULE_SETUP -#line 161 "lexer.l" +#line 201 "lexer.l" { - lmsg ("bysize"); + lmsg ("bysize\n"); return (BYSIZE); } YY_BREAK -case 27: +case 35: YY_RULE_SETUP -#line 166 "lexer.l" +#line 206 "lexer.l" { - lmsg ("byorder"); + lmsg ("byorder\n"); return (BYORDER); } YY_BREAK -case 28: +case 36: YY_RULE_SETUP -#line 171 "lexer.l" +#line 211 "lexer.l" { - lmsg ("byconnections"); + lmsg ("byconnections\n"); return (BYCONNECTIONS); } YY_BREAK -case 29: +case 37: YY_RULE_SETUP -#line 176 "lexer.l" +#line 216 "lexer.l" { - lmsg ("externalhandler"); + lmsg ("externalhandler\n"); BEGIN (stringstate); free (laststring); laststring = 0; return (EXTERNALHANDLER); } YY_BREAK -case 30: +case 38: YY_RULE_SETUP -#line 184 "lexer.l" +#line 224 "lexer.l" { - lmsg ("byclientip"); + lmsg ("byclientip\n"); return (BYCLIENTIP); } YY_BREAK -case 31: +case 39: YY_RULE_SETUP -#line 189 "lexer.l" +#line 229 "lexer.l" { - lmsg ("useraccount"); + lmsg ("useraccount\n"); BEGIN (stringstate); free (laststring); laststring = 0; return (USERACCOUNT); } YY_BREAK -case 32: +case 40: YY_RULE_SETUP -#line 197 "lexer.l" +#line 237 "lexer.l" { - lmsg ("revivinginterval"); + lmsg ("revivinginterval\n"); return (REVIVINGINTERVAL); } YY_BREAK -case 33: +case 41: YY_RULE_SETUP -#line 202 "lexer.l" +#line 242 "lexer.l" { - lmsg ("checkinterval"); + lmsg ("checkinterval\n"); return (CHECKINTERVAL); } YY_BREAK -case 34: +case 42: YY_RULE_SETUP -#line 207 "lexer.l" +#line 247 "lexer.l" { - lmsg ("type"); + lmsg ("type\n"); return (TYPE); } YY_BREAK -case 35: +case 43: YY_RULE_SETUP -#line 212 "lexer.l" +#line 252 "lexer.l" { - lmsg ("headerinspection"); + lmsg ("headerinspection\n"); return (HEADERINSPECTION); } YY_BREAK -case 36: +case 44: YY_RULE_SETUP -#line 217 "lexer.l" +#line 257 "lexer.l" { - lmsg ("deep"); + lmsg ("deep\n"); return (DEEP); } YY_BREAK -case 37: +case 45: YY_RULE_SETUP -#line 222 "lexer.l" +#line 262 "lexer.l" { - lmsg ("shallow"); + lmsg ("shallow\n"); return (SHALLOW); } YY_BREAK -case 38: +case 46: YY_RULE_SETUP -#line 227 "lexer.l" +#line 267 "lexer.l" { - lmsg ("any"); + lmsg ("any\n"); return (ANY); } YY_BREAK -case 39: +case 47: YY_RULE_SETUP -#line 232 "lexer.l" +#line 272 "lexer.l" { - lmsg ("stickyhttp"); + lmsg ("stickyhttp\n"); warning ("The 'stickyhttp protocol is obsolte.\n" "You should change to 'http'."); return (HTTP); } YY_BREAK -case 40: +case 48: YY_RULE_SETUP -#line 239 "lexer.l" +#line 279 "lexer.l" { - lmsg ("http"); + lmsg ("http\n"); return (HTTP); } YY_BREAK -case 41: +case 49: YY_RULE_SETUP -#line 244 "lexer.l" +#line 284 "lexer.l" { - lmsg ("throughputlog"); + lmsg ("throughputlog\n"); BEGIN (stringstate); free (laststring); laststring = 0; return (THROUGHPUTLOG); } YY_BREAK -case 42: +case 50: YY_RULE_SETUP -#line 252 "lexer.l" +#line 292 "lexer.l" { - lmsg ("trafficlog"); + lmsg ("trafficlog\n"); BEGIN (stringstate); free (laststring); laststring = 0; return (TRAFFICLOG); } YY_BREAK -case 43: +case 51: YY_RULE_SETUP -#line 260 "lexer.l" +#line 300 "lexer.l" { - lmsg ("dumptraffic"); + lmsg ("httptiminglog\n"); + BEGIN (stringstate); + free (laststring); + laststring = 0; + return (HTTPTIMINGLOG); +} + YY_BREAK +case 52: +YY_RULE_SETUP +#line 308 "lexer.l" +{ + lmsg ("dumptraffic\n"); warning ("The 'dumptraffic' statement is obsolete.\n" "You should change to 'trafficlog'."); BEGIN (stringstate); @@ -1318,343 +1453,376 @@ YY_RULE_SETUP return (TRAFFICLOG); } YY_BREAK -case 44: +case 53: YY_RULE_SETUP -#line 270 "lexer.l" +#line 318 "lexer.l" { - lmsg ("onstart"); + lmsg ("onstart\n"); BEGIN (stringstate); free (laststring); laststring = 0; return (ONSTART); } YY_BREAK -case 45: +case 54: YY_RULE_SETUP -#line 278 "lexer.l" +#line 326 "lexer.l" { - lmsg ("onfail"); + lmsg ("onfail\n"); BEGIN (stringstate); free (laststring); laststring = 0; return (ONFAIL); } YY_BREAK -case 46: +case 55: YY_RULE_SETUP -#line 286 "lexer.l" +#line 334 "lexer.l" { - lmsg ("onend"); + lmsg ("onend\n"); BEGIN (stringstate); free (laststring); laststring = 0; return (ONEND); } YY_BREAK -case 47: +case 56: YY_RULE_SETUP -#line 294 "lexer.l" +#line 342 "lexer.l" { - lmsg ("stickycookie"); + lmsg ("stickycookie\n"); BEGIN (stringstate); free (laststring); laststring = 0; return (STICKYCOOKIE); } YY_BREAK -case 48: +case 57: YY_RULE_SETUP -#line 302 "lexer.l" +#line 350 "lexer.l" { - lmsg ("addclientheader"); + lmsg ("addclientheader\n"); BEGIN (stringstate); free (laststring); laststring = 0; return (ADDCLIENTHEADER); } YY_BREAK -case 49: +case 58: YY_RULE_SETUP -#line 310 "lexer.l" +#line 358 "lexer.l" { - lmsg ("setclientheader"); + lmsg ("setclientheader\n"); BEGIN (stringstate); free (laststring); laststring = 0; return (SETCLIENTHEADER); } YY_BREAK -case 50: +case 59: YY_RULE_SETUP -#line 318 "lexer.l" +#line 366 "lexer.l" { - lmsg ("appendclientheader"); + lmsg ("appendclientheader\n"); BEGIN (stringstate); free (laststring); laststring = 0; return (APPENDCLIENTHEADER); } YY_BREAK -case 51: +case 60: YY_RULE_SETUP -#line 326 "lexer.l" +#line 374 "lexer.l" { - lmsg ("addserverheader"); + lmsg ("addserverheader\n"); BEGIN (stringstate); free (laststring); laststring = 0; return (ADDSERVERHEADER); } YY_BREAK -case 52: +case 61: YY_RULE_SETUP -#line 334 "lexer.l" +#line 382 "lexer.l" { - lmsg ("setserverheader"); + lmsg ("setserverheader\n"); BEGIN (stringstate); free (laststring); laststring = 0; return (SETSERVERHEADER); } YY_BREAK -case 53: +case 62: YY_RULE_SETUP -#line 342 "lexer.l" +#line 390 "lexer.l" { - lmsg ("appendserverheader"); + lmsg ("appendserverheader\n"); BEGIN (stringstate); free (laststring); laststring = 0; return (APPENDSERVERHEADER); } YY_BREAK -case 54: +case 63: YY_RULE_SETUP -#line 350 "lexer.l" +#line 398 "lexer.l" { - lmsg ("allowfrom"); + lmsg ("allowfrom\n"); BEGIN (stringstate); free (laststring); laststring = 0; return (ALLOWFROM); } YY_BREAK -case 55: +case 64: YY_RULE_SETUP -#line 358 "lexer.l" +#line 406 "lexer.l" { - lmsg ("denyfrom"); + lmsg ("denyfrom\n"); BEGIN (stringstate); free (laststring); laststring = 0; return (DENYFROM); } YY_BREAK -case 56: +case 65: YY_RULE_SETUP -#line 366 "lexer.l" +#line 414 "lexer.l" { - lmsg ("allowfile"); + lmsg ("allowfile\n"); BEGIN (stringstate); free (laststring); laststring = 0; return (ALLOWFILE); } YY_BREAK -case 57: +case 66: YY_RULE_SETUP -#line 374 "lexer.l" +#line 422 "lexer.l" { - lmsg ("denyfile"); + lmsg ("denyfile\n"); BEGIN (stringstate); free (laststring); laststring = 0; return (DENYFILE); } YY_BREAK -case 58: +case 67: YY_RULE_SETUP -#line 382 "lexer.l" +#line 430 "lexer.l" { - lmsg ("on"); + lmsg ("on\n"); return (ON); } YY_BREAK -case 59: +case 68: YY_RULE_SETUP -#line 387 "lexer.l" +#line 435 "lexer.l" { - lmsg ("off"); + lmsg ("off\n"); return (OFF); } YY_BREAK -case 60: +case 69: YY_RULE_SETUP -#line 392 "lexer.l" +#line 440 "lexer.l" { - llmsg ("identifier", yytext); + lmsg ("identifier [%s]\n", yytext); return (IDENTIFIER); } YY_BREAK -case 61: +case 70: YY_RULE_SETUP -#line 397 "lexer.l" +#line 445 "lexer.l" { - llmsg ("number", yytext); + lmsg ("number [%s]\n", yytext); return (NUMBER); } YY_BREAK -case 62: +case 71: YY_RULE_SETUP -#line 402 "lexer.l" +#line 450 "lexer.l" { - lmsg ("space(s)"); + lmsg ("space(s)\n"); } YY_BREAK -case 63: +case 72: YY_RULE_SETUP -#line 406 "lexer.l" +#line 454 "lexer.l" { - lmsg ("newline"); + lmsg ("newline\n"); yylineno++; } YY_BREAK -case 64: +case 73: YY_RULE_SETUP -#line 411 "lexer.l" +#line 459 "lexer.l" { - llmsg ("lone char", yytext); + lmsg ("lone char ['%c' (ASCII %d)]\n", + isprint(*yytext) ? *yytext : '.', + *yytext); return (*yytext); } YY_BREAK -case 65: +case 74: YY_RULE_SETUP -#line 416 "lexer.l" +#line 466 "lexer.l" { - lmsg ("C-comment starts"); + lmsg ("C-comment starts\n"); BEGIN(commentstate); } YY_BREAK -case 66: +case 75: YY_RULE_SETUP -#line 420 "lexer.l" +#line 470 "lexer.l" { - lmsg ("C-comment ends"); + lmsg ("C-comment ends\n"); BEGIN(0); } YY_BREAK -case 67: +case 76: YY_RULE_SETUP -#line 424 "lexer.l" +#line 474 "lexer.l" { yylineno++; } YY_BREAK -case 68: +case 77: YY_RULE_SETUP -#line 427 "lexer.l" +#line 477 "lexer.l" ; YY_BREAK -case 69: +case 78: +YY_RULE_SETUP +#line 479 "lexer.l" +{ + lmsg ("string state: skipping initial spaces [ASCII %d]\n", *yytext); + if (*yytext == '\n') + yylineno++; +} + YY_BREAK +case 79: +YY_RULE_SETUP +#line 484 "lexer.l" +{ + lmsg ("string state: entering instring on [%s (ASCII %d)]\n", + yytext, *yytext); + unput (*yytext); + BEGIN (instr); +} + YY_BREAK +case 80: YY_RULE_SETUP -#line 429 "lexer.l" +#line 491 "lexer.l" { - llmsg ("string part", yytext); + lmsg ("string part [%s]\n", yytext); + laststring = xstrcat (laststring, yytext); +} + YY_BREAK +case 81: +YY_RULE_SETUP +#line 496 "lexer.l" +{ + lmsg ("string part in double quotes [%s]\n", yytext); laststring = xstrcat (laststring, yytext + 1); laststring[strlen(laststring) - 1] = 0; } YY_BREAK -case 70: +case 82: YY_RULE_SETUP -#line 434 "lexer.l" +#line 501 "lexer.l" { - llmsg ("string part", yytext); + lmsg ("string part in single quotes [%s]\n", yytext); laststring = xstrcat (laststring, yytext + 1); laststring[strlen(laststring) - 1] = 0; } YY_BREAK -case 71: +case 83: YY_RULE_SETUP -#line 439 "lexer.l" +#line 506 "lexer.l" { BEGIN (0); + /* Strip terminating whitespace incase the ; is preceded by them */ + if (laststring && *laststring) + for (i = strlen(laststring) - 1; i >= 0 && isspace(laststring[i]); i--) + laststring[i] = 0; unput (';'); - llmsg ("string", laststring); + lmsg ("string complete [%s]\n", laststring); return (STRING); } YY_BREAK -case 72: +case 84: YY_RULE_SETUP -#line 445 "lexer.l" +#line 516 "lexer.l" { if (laststring) { laststring = xstrcat (laststring, yytext); - llmsg ("string part", yytext); + lmsg ("string part space [%s]\n", yytext); } } YY_BREAK -case 73: +case 85: YY_RULE_SETUP -#line 451 "lexer.l" +#line 522 "lexer.l" { - llmsg ("string part", yytext); + lmsg ("string part char [%s]\n", yytext); laststring = xstrcat (laststring, yytext); } YY_BREAK -case 74: +case 86: YY_RULE_SETUP -#line 455 "lexer.l" +#line 526 "lexer.l" { if (laststring) { laststring = xstrcat (laststring, " "); - lmsg ("string part: newline, now space"); + lmsg ("string part: newline, now space\n"); } yylineno++; } YY_BREAK -case 75: +case 87: YY_RULE_SETUP -#line 463 "lexer.l" +#line 534 "lexer.l" { - lmsg ("includefile"); + lmsg ("includefile\n"); /* parser_skipline(); */ parser_open (yytext); BEGIN (0); } YY_BREAK case YY_STATE_EOF(includestate): -#line 469 "lexer.l" +#line 540 "lexer.l" { error ("Unterminated #include"); } YY_BREAK -case 76: +case 88: YY_RULE_SETUP -#line 472 "lexer.l" +#line 543 "lexer.l" ; YY_BREAK -case 77: +case 89: YY_RULE_SETUP -#line 473 "lexer.l" +#line 544 "lexer.l" { yylineno++; } YY_BREAK -case 78: +case 90: YY_RULE_SETUP -#line 476 "lexer.l" +#line 547 "lexer.l" { error ("Illegal character 0x%2.2x in #include line", *yytext); } YY_BREAK -case 79: +case 91: YY_RULE_SETUP -#line 480 "lexer.l" +#line 551 "lexer.l" ; YY_BREAK -case 80: +case 92: YY_RULE_SETUP -#line 481 "lexer.l" +#line 552 "lexer.l" { symtab_start (yytext); BEGIN (defineredef); @@ -1663,56 +1831,57 @@ YY_RULE_SETUP case YY_STATE_EOF(definestate): case YY_STATE_EOF(defineredef): case YY_STATE_EOF(definesym): -#line 485 "lexer.l" +#line 556 "lexer.l" { error ("Unterminated #define"); } YY_BREAK -case 81: +case 93: YY_RULE_SETUP -#line 488 "lexer.l" +#line 559 "lexer.l" { error ("Unterminated #define"); } YY_BREAK -case 82: +case 94: YY_RULE_SETUP -#line 491 "lexer.l" +#line 562 "lexer.l" { error ("Unrecognized character '%c' in #define", *yytext); } YY_BREAK -case 83: +case 95: YY_RULE_SETUP -#line 495 "lexer.l" +#line 566 "lexer.l" { BEGIN (definesym); } YY_BREAK -case 84: +case 96: YY_RULE_SETUP -#line 498 "lexer.l" +#line 569 "lexer.l" { symtab_set (yytext); } YY_BREAK -case 85: +case 97: YY_RULE_SETUP -#line 501 "lexer.l" +#line 572 "lexer.l" { yylineno++; symtab_end(); BEGIN (0); } YY_BREAK -case 86: +case 98: YY_RULE_SETUP -#line 506 "lexer.l" +#line 577 "lexer.l" ECHO; YY_BREAK -#line 1709 "lexer.c" +#line 1877 "lexer.c" case YY_STATE_EOF(INITIAL): case YY_STATE_EOF(stringstate): +case YY_STATE_EOF(instr): case YY_STATE_EOF(commentstate): yyterminate(); @@ -2005,7 +2174,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 >= 513 ) + if ( yy_current_state >= 616 ) yy_c = yy_meta[(unsigned int) yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; @@ -2040,11 +2209,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 >= 513 ) + if ( yy_current_state >= 616 ) 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 == 512); + yy_is_jam = (yy_current_state == 615); return yy_is_jam ? 0 : yy_current_state; } @@ -2600,4 +2769,4 @@ int main() return 0; } #endif -#line 506 "lexer.l" +#line 577 "lexer.l" diff --git a/src/lib/lexer.l b/src/lib/lexer.l @@ -6,49 +6,89 @@ #define YY_INPUT(buf,res,max) (res) = parser_input( (buf), (max) ) #define yywrap parser_close +/* Globals */ +static int i; + /* Lexer debugging related */ -/* #define LEXER_DEBUG */ -#ifdef LEXER_DEBUG - static void lmsg (char const *x) { - printf ("L: %s\n", x); - } - static void llmsg (char const *x, char const *y) { - printf ("L: %s %s\n", x, y); +static void lmsg (char const *fmt, ...) { + va_list args; + + if (parser_debug) { + va_start (args, fmt); + printf ("LEXER: "); + vprintf (fmt, args); } -#else -# define lmsg(x) -# define llmsg(x,y) -#endif +} %} %pointer -%x stringstate commentstate includestate definestate defineredef definesym +%x stringstate instr commentstate includestate definestate defineredef definesym %% ^#[ \t]*include { - lmsg ("include starts"); + lmsg ("include starts\n"); BEGIN (includestate); } ^#[ \t]*define { - lmsg ("define starts"); + lmsg ("define starts\n"); BEGIN (definestate); } \/\/.*\n { - lmsg ("comment"); + lmsg ("comment\n"); yylineno++; } +options { + lmsg ("options\n"); + return (OPTIONS); +} + +logactivity { + lmsg ("logactivity\n"); + return (LOGACTIVITY); +} + +tcpbuffersize { + lmsg ("tcpbuffersize\n"); + return (TCPBUFFERSIZE); +} + +dnscachettl { + lmsg ("dnscachettl\n"); + return (DNSCACHETTL); +} + +logfacility { + lmsg ("logfacility\n"); + return (LOGFACILITY); +} + +shmpermissions { + lmsg ("shmpermissions\n"); + return (SHMPERMISSIONS); +} + +sloppyportbind { + lmsg ("sloppyportbind\n"); + return (SLOPPYPORTBIND); +} + +leaveprocesstitle { + lmsg ("leaveprocesstitle\n"); + return (LEAVEPROCESSTITLE); +} + service { - lmsg ("service"); + lmsg ("service\n"); return (SERVICE); } bindto { - lmsg ("bindto"); + lmsg ("bindto\n"); BEGIN (stringstate); free (laststring); laststring = 0; @@ -56,82 +96,82 @@ bindto { } port { - lmsg ("port"); + lmsg ("port\n"); return (PORT); } over { - lmsg ("over"); + lmsg ("over\n"); return (OVER); } shmkey { - lmsg ("shmkey"); + lmsg ("shmkey\n"); return (SHMKEY); } backend { - lmsg ("backend"); + lmsg ("backend\n"); return (BACKEND); } state { - lmsg ("state"); + lmsg ("state\n"); return (STATE); } (available)|(up) { - lmsg ("available"); + lmsg ("available\n"); return (AVAILABLE); } unavailable { - lmsg ("unavailable"); + lmsg ("unavailable\n"); return (UNAVAILABLE); } down { - lmsg ("down"); + lmsg ("down\n"); return (DOWN); } backlog { - lmsg ("backlog"); + lmsg ("backlog\n"); return (BACKLOG); } retries { - lmsg ("retries"); + lmsg ("retries\n"); return (RETRIES); } (verbosity)|(verbose) { - lmsg ("verbosity"); + lmsg ("verbosity\n"); return (VERBOSITY); } connectiontimeout { - lmsg ("connectiontimeout"); + lmsg ("connectiontimeout\n"); return (CONNECTIONTIMEOUT); } maxconnections { - lmsg ("maxconnections"); + lmsg ("maxconnections\n"); return (MAXCONNECTIONS); } weight { - lmsg ("weight"); + lmsg ("weight\n"); return (WEIGHT); } decay { - lmsg ("decay"); + lmsg ("decay\n"); return (DECAY); } server { - lmsg ("server"); + lmsg ("server\n"); BEGIN (stringstate); free (laststring); laststring = 0; @@ -139,42 +179,42 @@ server { } dispatchmode { - lmsg ("dispatchmode"); + lmsg ("dispatchmode\n"); return (DISPATCHMODE); } roundrobin { - lmsg ("roundrobin"); + lmsg ("roundrobin\n"); return (ROUNDROBIN); } random { - lmsg ("random"); + lmsg ("random\n"); return (RANDOM); } byduration { - lmsg ("byduration"); + lmsg ("byduration\n"); return (BYDURATION); } bysize { - lmsg ("bysize"); + lmsg ("bysize\n"); return (BYSIZE); } byorder { - lmsg ("byorder"); + lmsg ("byorder\n"); return (BYORDER); } byconnections { - lmsg ("byconnections"); + lmsg ("byconnections\n"); return (BYCONNECTIONS); } externalhandler { - lmsg ("externalhandler"); + lmsg ("externalhandler\n"); BEGIN (stringstate); free (laststring); laststring = 0; @@ -182,12 +222,12 @@ externalhandler { } byclientip { - lmsg ("byclientip"); + lmsg ("byclientip\n"); return (BYCLIENTIP); } useraccount { - lmsg ("useraccount"); + lmsg ("useraccount\n"); BEGIN (stringstate); free (laststring); laststring = 0; @@ -195,54 +235,54 @@ useraccount { } revivinginterval { - lmsg ("revivinginterval"); + lmsg ("revivinginterval\n"); return (REVIVINGINTERVAL); } checkinterval { - lmsg ("checkinterval"); + lmsg ("checkinterval\n"); return (CHECKINTERVAL); } type { - lmsg ("type"); + lmsg ("type\n"); return (TYPE); } headerinspection { - lmsg ("headerinspection"); + lmsg ("headerinspection\n"); return (HEADERINSPECTION); } deep { - lmsg ("deep"); + lmsg ("deep\n"); return (DEEP); } shallow { - lmsg ("shallow"); + lmsg ("shallow\n"); return (SHALLOW); } any { - lmsg ("any"); + lmsg ("any\n"); return (ANY); } stickyhttp { - lmsg ("stickyhttp"); + lmsg ("stickyhttp\n"); warning ("The 'stickyhttp protocol is obsolte.\n" "You should change to 'http'."); return (HTTP); } http { - lmsg ("http"); + lmsg ("http\n"); return (HTTP); } throughputlog { - lmsg ("throughputlog"); + lmsg ("throughputlog\n"); BEGIN (stringstate); free (laststring); laststring = 0; @@ -250,15 +290,23 @@ throughputlog { } trafficlog { - lmsg ("trafficlog"); + lmsg ("trafficlog\n"); BEGIN (stringstate); free (laststring); laststring = 0; return (TRAFFICLOG); } +httptiminglog { + lmsg ("httptiminglog\n"); + BEGIN (stringstate); + free (laststring); + laststring = 0; + return (HTTPTIMINGLOG); +} + dumptraffic { - lmsg ("dumptraffic"); + lmsg ("dumptraffic\n"); warning ("The 'dumptraffic' statement is obsolete.\n" "You should change to 'trafficlog'."); BEGIN (stringstate); @@ -268,7 +316,7 @@ dumptraffic { } onstart { - lmsg ("onstart"); + lmsg ("onstart\n"); BEGIN (stringstate); free (laststring); laststring = 0; @@ -276,7 +324,7 @@ onstart { } onfail { - lmsg ("onfail"); + lmsg ("onfail\n"); BEGIN (stringstate); free (laststring); laststring = 0; @@ -284,7 +332,7 @@ onfail { } onend { - lmsg ("onend"); + lmsg ("onend\n"); BEGIN (stringstate); free (laststring); laststring = 0; @@ -292,7 +340,7 @@ onend { } stickycookie { - lmsg ("stickycookie"); + lmsg ("stickycookie\n"); BEGIN (stringstate); free (laststring); laststring = 0; @@ -300,7 +348,7 @@ stickycookie { } addclientheader { - lmsg ("addclientheader"); + lmsg ("addclientheader\n"); BEGIN (stringstate); free (laststring); laststring = 0; @@ -308,7 +356,7 @@ addclientheader { } setclientheader { - lmsg ("setclientheader"); + lmsg ("setclientheader\n"); BEGIN (stringstate); free (laststring); laststring = 0; @@ -316,7 +364,7 @@ setclientheader { } appendclientheader { - lmsg ("appendclientheader"); + lmsg ("appendclientheader\n"); BEGIN (stringstate); free (laststring); laststring = 0; @@ -324,7 +372,7 @@ appendclientheader { } addserverheader { - lmsg ("addserverheader"); + lmsg ("addserverheader\n"); BEGIN (stringstate); free (laststring); laststring = 0; @@ -332,7 +380,7 @@ addserverheader { } setserverheader { - lmsg ("setserverheader"); + lmsg ("setserverheader\n"); BEGIN (stringstate); free (laststring); laststring = 0; @@ -340,7 +388,7 @@ setserverheader { } appendserverheader { - lmsg ("appendserverheader"); + lmsg ("appendserverheader\n"); BEGIN (stringstate); free (laststring); laststring = 0; @@ -348,7 +396,7 @@ appendserverheader { } allowfrom { - lmsg ("allowfrom"); + lmsg ("allowfrom\n"); BEGIN (stringstate); free (laststring); laststring = 0; @@ -356,7 +404,7 @@ allowfrom { } denyfrom { - lmsg ("denyfrom"); + lmsg ("denyfrom\n"); BEGIN (stringstate); free (laststring); laststring = 0; @@ -364,7 +412,7 @@ denyfrom { } allowfile { - lmsg ("allowfile"); + lmsg ("allowfile\n"); BEGIN (stringstate); free (laststring); laststring = 0; @@ -372,7 +420,7 @@ allowfile { } denyfile { - lmsg ("denyfile"); + lmsg ("denyfile\n"); BEGIN (stringstate); free (laststring); laststring = 0; @@ -380,45 +428,47 @@ denyfile { } on|true|yes { - lmsg ("on"); + lmsg ("on\n"); return (ON); } off|false|no { - lmsg ("off"); + lmsg ("off\n"); return (OFF); } [a-zA-Z_][a-zA-Z0-9_]* { - llmsg ("identifier", yytext); + lmsg ("identifier [%s]\n", yytext); return (IDENTIFIER); } [0-9]+ { - llmsg ("number", yytext); + lmsg ("number [%s]\n", yytext); return (NUMBER); } [ \t]+ { - lmsg ("space(s)"); + lmsg ("space(s)\n"); } \n { - lmsg ("newline"); + lmsg ("newline\n"); yylineno++; } . { - llmsg ("lone char", yytext); + lmsg ("lone char ['%c' (ASCII %d)]\n", + isprint(*yytext) ? *yytext : '.', + *yytext); return (*yytext); } \/\* { - lmsg ("C-comment starts"); + lmsg ("C-comment starts\n"); BEGIN(commentstate); } <commentstate>\*\/ { - lmsg ("C-comment ends"); + lmsg ("C-comment ends\n"); BEGIN(0); } <commentstate>\n { @@ -426,42 +476,63 @@ off|false|no { } <commentstate>. ; -<stringstate>\"[^\"]*\" { - llmsg ("string part", yytext); +<stringstate>[ \r\n\t] { + lmsg ("string state: skipping initial spaces [ASCII %d]\n", *yytext); + if (*yytext == '\n') + yylineno++; +} +<stringstate>. { + lmsg ("string state: entering instring on [%s (ASCII %d)]\n", + yytext, *yytext); + unput (*yytext); + BEGIN (instr); +} + +<instr>(\\\")|(\\\') { + lmsg ("string part [%s]\n", yytext); + laststring = xstrcat (laststring, yytext); +} + +<instr>\"[^\"]*\" { + lmsg ("string part in double quotes [%s]\n", yytext); laststring = xstrcat (laststring, yytext + 1); laststring[strlen(laststring) - 1] = 0; } -<stringstate>\'[^\']*\' { - llmsg ("string part", yytext); +<instr>\'[^\']*\' { + lmsg ("string part in single quotes [%s]\n", yytext); laststring = xstrcat (laststring, yytext + 1); laststring[strlen(laststring) - 1] = 0; } -<stringstate>; { +<instr>; { BEGIN (0); + /* Strip terminating whitespace incase the ; is preceded by them */ + if (laststring && *laststring) + for (i = strlen(laststring) - 1; i >= 0 && isspace(laststring[i]); i--) + laststring[i] = 0; unput (';'); - llmsg ("string", laststring); + lmsg ("string complete [%s]\n", laststring); return (STRING); } -<stringstate>" " { +<instr>" " { if (laststring) { laststring = xstrcat (laststring, yytext); - llmsg ("string part", yytext); + lmsg ("string part space [%s]\n", yytext); } } -<stringstate>. { - llmsg ("string part", yytext); +<instr>. { + lmsg ("string part char [%s]\n", yytext); laststring = xstrcat (laststring, yytext); } -<stringstate>\n { +<instr>\n { if (laststring) { laststring = xstrcat (laststring, " "); - lmsg ("string part: newline, now space"); + lmsg ("string part: newline, now space\n"); } yylineno++; } <includestate>[<>\"a-zA-Z0-9_\-\./:\\]+ { - lmsg ("includefile"); + lmsg ("includefile\n"); /* parser_skipline(); */ parser_open (yytext); BEGIN (0); diff --git a/src/lib/lockreporter.c b/src/lib/lockreporter.c @@ -1,5 +1,5 @@ /************************************************************************* - * This file is part of Crosroads 1.71, a load balancer and fail over + * This file is part of Crosroads 1.75, 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.71, a load balancer and fail over + * This file is part of Crosroads 1.75, a load balancer and fail over * utility for TCP. Copyright (c) Karel Kubat, distributed under GPL. * Visit http://crossroads.e-tunity.com for information. *************************************************************************/ @@ -7,10 +7,10 @@ #include "../crossroads.h" void log_activity_any (char const *action) { - if (!log_activity || current_backend < 0) + if (!opt.log_activity || current_backend < 0) return; if (!logstarted++) - openlog ("crossroads", LOG_PID, log_facility); + openlog ("crossroads", LOG_PID, opt.log_facility); syslog (LOG_NOTICE, "%s %s %s from %s to %s:%d", ansistamp(tm_localtime, 0), action, activeservice->name, client_ip, diff --git a/src/lib/logactivitycontinuation.c b/src/lib/logactivitycontinuation.c @@ -1,5 +1,5 @@ /************************************************************************* - * This file is part of Crosroads 1.71, a load balancer and fail over + * This file is part of Crosroads 1.75, 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.71, a load balancer and fail over + * This file is part of Crosroads 1.75, 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.71, a load balancer and fail over + * This file is part of Crosroads 1.75, 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.71, a load balancer and fail over + * This file is part of Crosroads 1.75, 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.71, a load balancer and fail over + * This file is part of Crosroads 1.75, a load balancer and fail over * utility for TCP. Copyright (c) Karel Kubat, distributed under GPL. * Visit http://crossroads.e-tunity.com for information. *************************************************************************/ @@ -25,11 +25,12 @@ void mark_activity (double nbytes, double nsec, * Upon other state, set fails count to zero. */ if (newstate == st_unavailable && servicereport->backendstate[current_backend].actual_avail != - st_unavailable) { + st_unavailable && + program_stage != stage_retrying) { servicereport->backendstate[current_backend].fail++; - // msg ("Service %s: Back end %d's unavailability increased to %d", - // activeservice->name, current_backend, - // servicereport->backendstate[current_backend].fail); + msg ("Service %s: Back end %d's fail count increased to %d", + activeservice->name, current_backend, + servicereport->backendstate[current_backend].fail); } else if (newstate == st_available) servicereport->backendstate[current_backend].fail = 0; diff --git a/src/lib/msg.c b/src/lib/msg.c @@ -1,5 +1,5 @@ /************************************************************************* - * This file is part of Crosroads 1.71, a load balancer and fail over + * This file is part of Crosroads 1.75, a load balancer and fail over * utility for TCP. Copyright (c) Karel Kubat, distributed under GPL. * Visit http://crossroads.e-tunity.com for information. *************************************************************************/ @@ -18,6 +18,6 @@ void msg (char const *fmt, ...) { fprintf (stderr, "INFO: %s\n", str); else writelog (LOG_NOTICE, "INFO: %s", str); - + free (str); va_end (args); } diff --git a/src/lib/msgdumpbuf.c b/src/lib/msgdumpbuf.c @@ -1,5 +1,5 @@ /************************************************************************* - * This file is part of Crosroads 1.71, a load balancer and fail over + * This file is part of Crosroads 1.75, 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/netallocbufs.c b/src/lib/netallocbufs.c @@ -1,5 +1,5 @@ /************************************************************************* - * This file is part of Crosroads 1.71, a load balancer and fail over + * This file is part of Crosroads 1.75, a load balancer and fail over * utility for TCP. Copyright (c) Karel Kubat, distributed under GPL. * Visit http://crossroads.e-tunity.com for information. *************************************************************************/ @@ -8,10 +8,10 @@ void net_allocbufs () { if (!clbuf) { - clbuf = xmalloc (tcp_bufsz + 1); - clbuf[tcp_bufsz] = 0; - srbuf = xmalloc (tcp_bufsz + 1); - srbuf[tcp_bufsz] = 0; + clbuf = xmalloc (opt.tcp_bufsz + 1); + clbuf[opt.tcp_bufsz] = 0; + srbuf = xmalloc (opt.tcp_bufsz + 1); + srbuf[opt.tcp_bufsz] = 0; clbufmax = srbufmax = clbufpos = srbufpos = 0; msg ("Service %s: Allocated client and server buffers", activeservice->name); diff --git a/src/lib/netbuffer.c b/src/lib/netbuffer.c @@ -1,5 +1,5 @@ /************************************************************************* - * This file is part of Crosroads 1.71, a load balancer and fail over + * This file is part of Crosroads 1.75, 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.71, a load balancer and fail over + * This file is part of Crosroads 1.75, a load balancer and fail over * utility for TCP. Copyright (c) Karel Kubat, distributed under GPL. * Visit http://crossroads.e-tunity.com for information. *************************************************************************/ @@ -27,7 +27,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, opt.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.71, a load balancer and fail over + * This file is part of Crosroads 1.75, 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.71, a load balancer and fail over + * This file is part of Crosroads 1.75, 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.71, a load balancer and fail over + * This file is part of Crosroads 1.75, a load balancer and fail over * utility for TCP. Copyright (c) Karel Kubat, distributed under GPL. * Visit http://crossroads.e-tunity.com for information. *************************************************************************/ @@ -53,16 +53,30 @@ int net_write (int sock, unsigned char const *buf, int buflen, } else tvp = 0; if ( (nfd = select (FD_SETSIZE, 0, &fdset, &exset, tvp)) < 1) { - if (!nfd) - warning ("Service %s: Timout while writing %s on socket %d", - activeservice->name, - is_client ? "client" : "server", sock); - else - warning ("Service %s: Failed to wait for network of %s " - "on socket %d", - activeservice->name, - is_client ? "client" : "server", sock); - + if (!nfd) { + /* Issue an appropriate warning for TIMEOUTS */ + if (is_client) + warning ("Service %s: Timeout while writing client " + "on socket %d", activeservice->name, sock); + else + warning ("Service %s: Timeout while writing backend %s " + "on socket %d", + activeservice->name, + activeservice->backend[current_backend].name, + sock); + } else { + /* Issue an appropriate warning for NETWORK ERRORS */ + if (is_client) + warning ("Service %s: Select failed while writing client " + "on socket %d", activeservice->name, sock); + else + warning ("Service %s: Select failed while writing backend %s " + "on socket %d", + activeservice->name, + activeservice->backend[current_backend].name, + sock); + } + decr_client_count(); log_activity_end(); exit (0); diff --git a/src/lib/optionsread.c b/src/lib/optionsread.c @@ -0,0 +1,27 @@ +/************************************************************************* + * This file is part of Crosroads 1.75, 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 options_read (int fd) { + int res; + + if ( (res = read (fd, &opt, sizeof(Options))) != sizeof(Options) ) + error ("Received only %d bytes (out of %d) " + "while reading options on fd %d", + res, sizeof(Options), fd); + +# ifdef DEBUG + printf ("Option log_activity: %d\n", opt.log_activity); + printf ("Option tcp_bufsz: %u\n", opt.tcp_bufsz); + printf ("Option dns_cachettl: %d\n", opt.dns_cachettl); + printf ("Option log_facility: %d\n", opt.log_facility); + printf ("Option shmperm: %d\n", opt.shmperm); + printf ("Option sloppyportbind: %d\n", opt.sloppyportbind); + printf ("Option leave_proctitle: %d\n", opt.leave_proctitle); + printf ("Option log_http_activity: %d\n", opt.log_http_activity); +# endif +} diff --git a/src/lib/optionswrite.c b/src/lib/optionswrite.c @@ -0,0 +1,16 @@ +/************************************************************************* + * This file is part of Crosroads 1.75, 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 options_write (int fd) { + int res; + + msg ("Writing binary program options to fd %d", fd); + if ( (res = write (fd, &opt, sizeof(Options))) != sizeof(Options) ) + error ("Failed to transmit options, sent %d bytes of %d", + res, sizeof(Options)); +} diff --git a/src/lib/parser.c b/src/lib/parser.c @@ -1,5 +1,5 @@ /************************************************************************* - * This file is part of Crosroads 1.71, a load balancer and fail over + * This file is part of Crosroads 1.75, a load balancer and fail over * utility for TCP. Copyright (c) Karel Kubat, distributed under GPL. * Visit http://crossroads.e-tunity.com for information. *************************************************************************/ @@ -45,29 +45,38 @@ #define BACKLOG 290 #define THROUGHPUTLOG 291 #define TRAFFICLOG 292 -#define STICKYCOOKIE 293 -#define ADDCLIENTHEADER 294 -#define SETCLIENTHEADER 295 -#define APPENDCLIENTHEADER 296 -#define ADDSERVERHEADER 297 -#define SETSERVERHEADER 298 -#define APPENDSERVERHEADER 299 -#define ALLOWFROM 300 -#define DENYFROM 301 -#define ALLOWFILE 302 -#define DENYFILE 303 -#define EXTERNALHANDLER 304 -#define USERACCOUNT 305 -#define ONEND 306 -#define HEADERINSPECTION 307 -#define DEEP 308 -#define SHALLOW 309 -#define STATE 310 -#define AVAILABLE 311 -#define UNAVAILABLE 312 -#define DOWN 313 - -#line 3 "parser.y" +#define HTTPTIMINGLOG 293 +#define STICKYCOOKIE 294 +#define ADDCLIENTHEADER 295 +#define SETCLIENTHEADER 296 +#define APPENDCLIENTHEADER 297 +#define ADDSERVERHEADER 298 +#define SETSERVERHEADER 299 +#define APPENDSERVERHEADER 300 +#define ALLOWFROM 301 +#define DENYFROM 302 +#define ALLOWFILE 303 +#define DENYFILE 304 +#define EXTERNALHANDLER 305 +#define USERACCOUNT 306 +#define ONEND 307 +#define HEADERINSPECTION 308 +#define DEEP 309 +#define SHALLOW 310 +#define STATE 311 +#define AVAILABLE 312 +#define UNAVAILABLE 313 +#define DOWN 314 +#define OPTIONS 315 +#define LOGACTIVITY 316 +#define TCPBUFFERSIZE 317 +#define DNSCACHETTL 318 +#define LOGFACILITY 319 +#define SHMPERMISSIONS 320 +#define SLOPPYPORTBIND 321 +#define LEAVEPROCESSTITLE 322 + +#line 4 "parser.y" /* Prologue */ #include "../crossroads.h" @@ -80,22 +89,15 @@ static Backend cur_backend; /* Storage for a handled backend */ static Service cur_service; /* Storage for a handled service */ /* Parser debugging related */ -/* #define PARSER_DEBUG */ -#ifdef PARSER_DEBUG - static void pmsg (char const *x) { - printf ("P: %s\n", x); - } - static void psmsg (char const *x, char const *y) { - printf ("P: %s %s\n", x, y); - } - static void pimsg(char const *x, int y) { - printf ("P: %s %d\n", x, y); +static void pmsg (char const *fmt, ...) { + va_list args; + + if (parser_debug) { + printf ("PARSER: "); + va_start (args, fmt); + vprintf (fmt, args); } -#else -# define pmsg(x) -# define psmsg(x,y) -# define pimsg(x,y) -#endif +} /* Conversion of yytext for symbol table */ #define SYMBOL (symtab_lookup((yytext))) @@ -128,13 +130,19 @@ static void setlaststr (char const *what) { /* Store an encountered number */ static int lastnr; static void setlastnr (char const *what) { - lastnr = atoi (what); + if (what && *what && *what == '0') + lastnr = strtol (what, 0, 8); + else + lastnr = atoi (what); } /* Store an encountered 'over' number */ static int lastovernr; static void setlastovernr (char const *what) { - lastovernr = atoi(what); + if (what && *what && *what == '0') + lastovernr = strtol (what, 0, 8); + else + lastovernr = atoi(what); } /* Store an encountered 'externalhandler' */ @@ -210,11 +218,11 @@ static void setuseraccount (char *username) { -#define YYFINAL 228 +#define YYFINAL 277 #define YYFLAG -32768 -#define YYNTBASE 63 +#define YYNTBASE 72 -#define YYTRANSLATE(x) ((unsigned)(x) <= 313 ? yytranslate[x] : 154) +#define YYTRANSLATE(x) ((unsigned)(x) <= 322 ? yytranslate[x] : 181) static const char yytranslate[] = { 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, @@ -222,14 +230,14 @@ static const char yytranslate[] = { 0, 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, 62, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 69, 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, 60, 2, 61, 2, 2, 2, 2, 2, + 2, 2, 70, 2, 71, 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, @@ -248,88 +256,102 @@ static const char yytranslate[] = { 0, 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, 52, 53, 54, 55, 56, - 57, 58, 59 + 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, + 67, 68 }; #if YYDEBUG != 0 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, 59, 61, 65, 69, 72, - 75, 78, 83, 85, 87, 92, 94, 96, 97, 100, - 103, 105, 108, 110, 112, 114, 116, 118, 120, 122, - 124, 128, 131, 136, 141, 143, 144, 147, 151, 155, - 159, 163, 167, 170, 172, 174, 178, 181, 183, 185, - 189, 193, 197, 201, 204, 210, 213, 216, 218, 221, - 223, 225, 227, 229, 231, 233, 235, 237, 239, 241, - 243, 245, 247, 249, 251, 253, 255, 257, 259, 261, - 266, 270, 274, 276, 280, 284, 287, 289, 291, 293, - 297, 301, 305, 309, 313, 316, 319, 323, 326, 330, - 334, 338, 342, 346, 350, 353, 354, 355, 356, 357, - 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, - 368, 369, 370, 371, 372 + 0, 3, 5, 7, 9, 14, 17, 19, 22, 24, + 26, 28, 30, 32, 34, 36, 41, 45, 49, 53, + 57, 62, 67, 73, 76, 79, 82, 84, 87, 89, + 91, 93, 95, 97, 99, 101, 103, 105, 107, 109, + 111, 113, 115, 117, 119, 121, 123, 127, 131, 134, + 137, 140, 145, 147, 149, 154, 156, 158, 159, 162, + 165, 167, 170, 172, 174, 176, 178, 180, 182, 184, + 186, 190, 193, 198, 203, 205, 206, 209, 213, 217, + 221, 225, 229, 232, 234, 236, 240, 243, 245, 247, + 251, 255, 259, 263, 266, 272, 275, 278, 280, 283, + 285, 287, 289, 291, 293, 295, 297, 299, 301, 303, + 305, 307, 309, 311, 313, 315, 317, 319, 321, 323, + 325, 330, 334, 338, 340, 344, 348, 351, 353, 355, + 357, 361, 365, 369, 373, 377, 381, 384, 387, 391, + 394, 398, 402, 406, 410, 414, 418, 421, 422, 423, + 424, 425, 426, 427, 428, 429, 430, 431, 432, 433, + 434, 435, 436, 437, 438, 439, 440, 441, 444, 447, + 448, 449 }; -static const short yyrhs[] = { 63, - 64, 0, 64, 0, 65, 66, 60, 67, 61, 0, - 138, 6, 0, 146, 3, 0, 67, 68, 0, 68, - 0, 140, 69, 0, 70, 0, 71, 0, 75, 0, - 77, 0, 86, 0, 87, 0, 90, 0, 91, 0, - 92, 0, 93, 0, 94, 0, 97, 0, 100, 0, - 102, 0, 101, 0, 103, 0, 84, 0, 105, 0, - 7, 73, 74, 0, 15, 72, 74, 0, 148, 5, - 0, 136, 4, 0, 141, 62, 0, 8, 142, 76, - 74, 0, 17, 0, 18, 0, 19, 82, 78, 74, - 0, 79, 0, 81, 0, 0, 27, 80, 0, 136, - 4, 0, 123, 0, 143, 83, 0, 20, 0, 21, - 0, 22, 0, 23, 0, 25, 0, 24, 0, 50, - 0, 26, 0, 51, 85, 74, 0, 152, 5, 0, - 29, 73, 88, 74, 0, 30, 73, 88, 74, 0, - 89, 0, 0, 50, 123, 0, 36, 73, 74, 0, - 32, 73, 74, 0, 16, 73, 74, 0, 9, 73, - 74, 0, 10, 95, 74, 0, 149, 96, 0, 11, - 0, 12, 0, 53, 98, 74, 0, 150, 99, 0, - 54, 0, 55, 0, 46, 104, 74, 0, 47, 104, - 74, 0, 48, 124, 74, 0, 49, 124, 74, 0, - 151, 5, 0, 13, 106, 60, 107, 61, 0, 147, - 3, 0, 107, 108, 0, 108, 0, 139, 109, 0, - 110, 0, 70, 0, 75, 0, 118, 0, 120, 0, - 119, 0, 121, 0, 122, 0, 111, 0, 112, 0, - 93, 0, 125, 0, 127, 0, 128, 0, 129, 0, - 130, 0, 131, 0, 132, 0, 114, 0, 115, 0, - 14, 137, 113, 74, 0, 33, 73, 74, 0, 28, - 73, 74, 0, 5, 0, 31, 73, 74, 0, 56, - 116, 74, 0, 153, 117, 0, 57, 0, 58, 0, - 59, 0, 34, 123, 74, 0, 35, 123, 74, 0, - 52, 123, 74, 0, 38, 124, 74, 0, 37, 124, - 74, 0, 144, 5, 0, 145, 5, 0, 39, 126, - 74, 0, 135, 5, 0, 40, 133, 74, 0, 41, - 133, 74, 0, 42, 133, 74, 0, 43, 133, 74, - 0, 44, 133, 74, 0, 45, 133, 74, 0, 134, - 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, +static const short yyrhs[] = { 72, + 73, 0, 73, 0, 85, 0, 74, 0, 61, 176, + 75, 177, 0, 75, 76, 0, 76, 0, 180, 77, + 0, 78, 0, 79, 0, 80, 0, 81, 0, 82, + 0, 83, 0, 84, 0, 62, 164, 97, 95, 0, + 63, 94, 95, 0, 64, 94, 95, 0, 65, 94, + 95, 0, 66, 94, 95, 0, 67, 164, 97, 95, + 0, 68, 164, 97, 95, 0, 86, 87, 176, 88, + 177, 0, 160, 6, 0, 168, 3, 0, 88, 89, + 0, 89, 0, 162, 90, 0, 91, 0, 92, 0, + 96, 0, 98, 0, 107, 0, 108, 0, 111, 0, + 112, 0, 113, 0, 114, 0, 115, 0, 118, 0, + 121, 0, 123, 0, 122, 0, 124, 0, 105, 0, + 126, 0, 7, 94, 95, 0, 15, 93, 95, 0, + 170, 5, 0, 158, 4, 0, 163, 69, 0, 8, + 164, 97, 95, 0, 17, 0, 18, 0, 19, 103, + 99, 95, 0, 100, 0, 102, 0, 0, 27, 101, + 0, 158, 4, 0, 145, 0, 165, 104, 0, 20, + 0, 21, 0, 22, 0, 23, 0, 25, 0, 24, + 0, 51, 0, 26, 0, 52, 106, 95, 0, 174, + 5, 0, 29, 94, 109, 95, 0, 30, 94, 109, + 95, 0, 110, 0, 0, 51, 145, 0, 36, 94, + 95, 0, 32, 94, 95, 0, 16, 94, 95, 0, + 9, 94, 95, 0, 10, 116, 95, 0, 171, 117, + 0, 11, 0, 12, 0, 54, 119, 95, 0, 172, + 120, 0, 55, 0, 56, 0, 47, 125, 95, 0, + 48, 125, 95, 0, 49, 146, 95, 0, 50, 146, + 95, 0, 173, 5, 0, 13, 127, 176, 128, 177, + 0, 169, 3, 0, 128, 129, 0, 129, 0, 161, + 130, 0, 131, 0, 91, 0, 96, 0, 139, 0, + 141, 0, 140, 0, 142, 0, 143, 0, 144, 0, + 132, 0, 133, 0, 114, 0, 147, 0, 149, 0, + 150, 0, 151, 0, 152, 0, 153, 0, 154, 0, + 135, 0, 136, 0, 14, 159, 134, 95, 0, 33, + 94, 95, 0, 28, 94, 95, 0, 5, 0, 31, + 94, 95, 0, 57, 137, 95, 0, 175, 138, 0, + 58, 0, 59, 0, 60, 0, 34, 145, 95, 0, + 35, 145, 95, 0, 53, 145, 95, 0, 38, 146, + 95, 0, 37, 146, 95, 0, 39, 146, 95, 0, + 166, 5, 0, 167, 5, 0, 40, 148, 95, 0, + 157, 5, 0, 41, 155, 95, 0, 42, 155, 95, + 0, 43, 155, 95, 0, 44, 155, 95, 0, 45, + 155, 95, 0, 46, 155, 95, 0, 156, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 178, 70, 0, 179, 71, 0, 0, 0, 0 }; #endif #if YYDEBUG != 0 static const short yyrline[] = { 0, - 158, 161, 165, 189, 194, 205, 208, 212, 217, 223, - 229, 235, 245, 253, 260, 266, 272, 278, 284, 290, - 296, 302, 308, 314, 320, 327, 502, 514, 526, 535, - 542, 547, 560, 564, 570, 579, 581, 583, 589, 606, - 613, 623, 632, 636, 640, 644, 648, 652, 656, 660, - 666, 678, 687, 705, 723, 725, 731, 740, 752, 764, - 776, 788, 800, 805, 809, 815, 827, 832, 836, 842, - 854, 866, 878, 890, 899, 909, 921, 929, 935, 942, - 947, 952, 957, 962, 967, 972, 977, 982, 987, 992, - 997, 1002, 1007, 1012, 1017, 1022, 1027, 1032, 1037, 1044, - 1057, 1069, 1081, 1087, 1099, 1111, 1116, 1120, 1124, 1130, - 1142, 1154, 1166, 1178, 1190, 1199, 1208, 1220, 1229, 1241, - 1253, 1265, 1277, 1289, 1301, 1310, 1315, 1320, 1325, 1330, - 1335, 1340, 1345, 1350, 1355, 1360, 1365, 1370, 1375, 1380, - 1385, 1390, 1395, 1400, 1405 + 160, 163, 167, 169, 173, 180, 183, 187, 192, 194, + 196, 198, 200, 202, 204, 208, 217, 225, 233, 241, + 249, 258, 267, 291, 296, 307, 310, 314, 319, 325, + 331, 337, 347, 355, 362, 368, 374, 380, 386, 392, + 398, 404, 410, 416, 422, 429, 615, 627, 639, 648, + 655, 660, 673, 677, 683, 692, 694, 696, 702, 719, + 726, 736, 745, 749, 753, 757, 761, 765, 769, 773, + 779, 791, 800, 818, 836, 838, 844, 853, 865, 877, + 889, 901, 913, 918, 922, 928, 940, 945, 949, 955, + 967, 979, 991, 1003, 1012, 1022, 1034, 1042, 1048, 1055, + 1060, 1065, 1070, 1075, 1080, 1085, 1090, 1095, 1100, 1105, + 1110, 1115, 1120, 1125, 1130, 1135, 1140, 1145, 1150, 1155, + 1162, 1175, 1187, 1199, 1205, 1217, 1229, 1234, 1238, 1242, + 1248, 1260, 1272, 1284, 1296, 1308, 1320, 1329, 1338, 1350, + 1359, 1371, 1383, 1395, 1407, 1419, 1431, 1440, 1445, 1450, + 1455, 1460, 1465, 1470, 1475, 1480, 1485, 1490, 1495, 1500, + 1505, 1510, 1515, 1520, 1525, 1530, 1535, 1540, 1545, 1550, + 1554, 1558 }; #endif @@ -341,54 +363,65 @@ static const char * const yytname[] = { "$","error","$undefined.","IDENTIFIER" "HTTP","BACKEND","SERVER","BINDTO","CONNECTIONTIMEOUT","ON","OFF","DISPATCHMODE", "ROUNDROBIN","RANDOM","BYDURATION","BYSIZE","BYCONNECTIONS","BYORDER","BYCLIENTIP", "OVER","DECAY","REVIVINGINTERVAL","CHECKINTERVAL","RETRIES","SHMKEY","WEIGHT", -"ONSTART","ONFAIL","BACKLOG","THROUGHPUTLOG","TRAFFICLOG","STICKYCOOKIE","ADDCLIENTHEADER", -"SETCLIENTHEADER","APPENDCLIENTHEADER","ADDSERVERHEADER","SETSERVERHEADER","APPENDSERVERHEADER", -"ALLOWFROM","DENYFROM","ALLOWFILE","DENYFILE","EXTERNALHANDLER","USERACCOUNT", -"ONEND","HEADERINSPECTION","DEEP","SHALLOW","STATE","AVAILABLE","UNAVAILABLE", -"DOWN","'{'","'}'","';'","input","element","service","servicename","servicestatements", -"servicestatement","servicebody","portstatement","bindstatement","ipaddress", -"number","semicol","verbositystatement","onoff","dispatchmodestatement","dispatchtail", -"dispatchover","overnumber","dispatchext","dispatchmethod","dispatchmethodspec", -"useraccountstatement","useraccount","revivingintervalstatement","checkintervalstatement", -"opt_externalhandler","externalhandler","backlogstatement","shmkeystatement", -"connectiontimeoutstatement","maxconnectionsstatement","typestatement","typespec", -"typespecifier","inspectionstatement","shallowdeepspec","shallowdeepspecifier", -"allowfromstatement","denyfromstatement","allowfilestatement","denyfilestatement", -"ipfilters","backendblock","backendname","backenddefinitions","backenddefinition", -"backendstatement","serverstatement","weightstatement","decaystatement","serveraddress", -"retriesstatement","initialstatestatement","statedef","somestate","onstartstatement", -"onfailstatement","onendstatement","dumptrafficstatement","throughputstatement", -"commandline","filename","stickycookiestatement","cookiespecifier","addclientheaderstatement", +"ONSTART","ONFAIL","BACKLOG","THROUGHPUTLOG","TRAFFICLOG","HTTPTIMINGLOG","STICKYCOOKIE", +"ADDCLIENTHEADER","SETCLIENTHEADER","APPENDCLIENTHEADER","ADDSERVERHEADER","SETSERVERHEADER", +"APPENDSERVERHEADER","ALLOWFROM","DENYFROM","ALLOWFILE","DENYFILE","EXTERNALHANDLER", +"USERACCOUNT","ONEND","HEADERINSPECTION","DEEP","SHALLOW","STATE","AVAILABLE", +"UNAVAILABLE","DOWN","OPTIONS","LOGACTIVITY","TCPBUFFERSIZE","DNSCACHETTL","LOGFACILITY", +"SHMPERMISSIONS","SLOPPYPORTBIND","LEAVEPROCESSTITLE","';'","'{'","'}'","input", +"element","option_element","option_statements","option_statement","optstat", +"logactivity_statement","tcpbuffersize_statement","dnscachettl_statement","logfacility_statement", +"shmpermissions_statement","sloppyportbind_statement","leaveprocesstitle_statement", +"service_element","service","servicename","servicestatements","servicestatement", +"servicebody","portstatement","bindstatement","ipaddress","number","semicol", +"verbositystatement","onoff","dispatchmodestatement","dispatchtail","dispatchover", +"overnumber","dispatchext","dispatchmethod","dispatchmethodspec","useraccountstatement", +"useraccount","revivingintervalstatement","checkintervalstatement","opt_externalhandler", +"externalhandler","backlogstatement","shmkeystatement","connectiontimeoutstatement", +"maxconnectionsstatement","typestatement","typespec","typespecifier","inspectionstatement", +"shallowdeepspec","shallowdeepspecifier","allowfromstatement","denyfromstatement", +"allowfilestatement","denyfilestatement","ipfilters","backendblock","backendname", +"backenddefinitions","backenddefinition","backendstatement","serverstatement", +"weightstatement","decaystatement","serveraddress","retriesstatement","initialstatestatement", +"statedef","somestate","onstartstatement","onfailstatement","onendstatement", +"dumptrafficstatement","throughputstatement","httptiminglogstatement","commandline", +"filename","stickycookiestatement","cookiespecifier","addclientheaderstatement", "setclientheaderstatement","appendclientheaderstatement","addserverheaderstatement", "setserverheaderstatement","appendserverheaderstatement","headerstring","headerstring_expected", "cookie_expected","number_expected","serveraddress_expected","service_expected", "backendstatement_expected","servicebody_expected","semicol_expected","onoff_expected", "dispatchmethod_expected","commandline_expected","filename_expected","servicename_expected", "backendname_expected","ipaddress_expected","type_expected","shallowdeep_expected", -"ipfilters_expected","useraccount_expected","statedef_expected", NULL +"ipfilters_expected","useraccount_expected","statedef_expected","openbrace", +"closebrace","openbrace_expected","closebrace_expected","option_statement_expected", NULL }; #endif static const short yyr1[] = { 0, - 63, 63, 64, 65, 66, 67, 67, 68, 69, 69, - 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, - 69, 69, 69, 69, 69, 69, 70, 71, 72, 73, - 74, 75, 76, 76, 77, 78, 78, 78, 79, 80, - 81, 82, 83, 83, 83, 83, 83, 83, 83, 83, - 84, 85, 86, 87, 88, 88, 89, 90, 91, 92, - 93, 94, 95, 96, 96, 97, 98, 99, 99, 100, - 101, 102, 103, 104, 105, 106, 107, 107, 108, 109, - 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, - 109, 109, 109, 109, 109, 109, 109, 109, 109, 110, - 111, 112, 113, 114, 115, 116, 117, 117, 117, 118, - 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, - 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, + 72, 72, 73, 73, 74, 75, 75, 76, 77, 77, + 77, 77, 77, 77, 77, 78, 79, 80, 81, 82, + 83, 84, 85, 86, 87, 88, 88, 89, 90, 90, + 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, + 90, 90, 90, 90, 90, 90, 91, 92, 93, 94, + 95, 96, 97, 97, 98, 99, 99, 99, 100, 101, + 102, 103, 104, 104, 104, 104, 104, 104, 104, 104, + 105, 106, 107, 108, 109, 109, 110, 111, 112, 113, + 114, 115, 116, 117, 117, 118, 119, 120, 120, 121, + 122, 123, 124, 125, 126, 127, 128, 128, 129, 130, + 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, + 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, + 131, 132, 133, 134, 135, 136, 137, 138, 138, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, - 149, 150, 151, 152, 153 + 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, + 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, + 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, + 179, 180 }; static const short yyr2[] = { 0, - 2, 1, 5, 2, 2, 2, 1, 2, 1, 1, + 2, 1, 1, 1, 4, 2, 1, 2, 1, 1, + 1, 1, 1, 1, 1, 4, 3, 3, 3, 3, + 4, 4, 5, 2, 2, 2, 1, 2, 1, 1, 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, @@ -397,138 +430,165 @@ static const short yyr2[] = { 0, 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, 4, - 3, 3, 1, 3, 3, 2, 1, 1, 1, 3, - 3, 3, 3, 3, 2, 2, 3, 2, 3, 3, - 3, 3, 3, 3, 2, 0, 0, 0, 0, 0, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 4, 3, 3, 1, 3, 3, 2, 1, 1, 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, 2, 2, 0, + 0, 0 }; -static const short yydefact[] = { 130, - 130, 2, 138, 0, 1, 0, 0, 4, 132, 5, - 132, 7, 0, 3, 6, 128, 134, 128, 141, 139, - 140, 128, 135, 128, 128, 128, 128, 143, 143, 137, - 137, 144, 142, 8, 9, 10, 11, 12, 25, 13, - 14, 15, 16, 17, 18, 19, 20, 21, 23, 22, - 24, 26, 133, 0, 0, 133, 133, 0, 0, 0, - 133, 0, 133, 38, 0, 56, 56, 133, 133, 133, - 0, 133, 133, 0, 133, 133, 0, 133, 0, 27, - 0, 30, 33, 34, 133, 61, 62, 64, 65, 63, - 131, 76, 28, 29, 60, 128, 133, 36, 37, 41, - 0, 43, 44, 45, 46, 48, 47, 50, 49, 42, - 136, 133, 55, 133, 59, 58, 70, 74, 71, 72, - 116, 73, 51, 52, 66, 68, 69, 67, 31, 32, - 131, 78, 0, 39, 0, 35, 115, 57, 53, 54, - 75, 77, 129, 128, 128, 128, 136, 136, 137, 137, - 127, 126, 126, 126, 126, 126, 126, 136, 145, 81, - 82, 90, 79, 80, 88, 89, 98, 99, 83, 85, - 84, 86, 87, 91, 92, 93, 94, 95, 96, 97, - 40, 0, 133, 133, 133, 133, 133, 133, 133, 133, - 0, 133, 0, 133, 133, 133, 133, 133, 133, 133, - 0, 103, 133, 102, 104, 101, 110, 111, 114, 113, - 117, 118, 119, 125, 120, 121, 122, 123, 124, 112, - 105, 107, 108, 109, 106, 100, 0, 0 +static const short yydefact[] = { 152, + 170, 152, 2, 4, 3, 160, 0, 172, 0, 1, + 170, 0, 24, 172, 7, 0, 168, 154, 25, 6, + 5, 0, 156, 150, 150, 150, 150, 156, 156, 8, + 9, 10, 11, 12, 13, 14, 15, 154, 27, 0, + 169, 0, 155, 0, 155, 155, 155, 0, 0, 26, + 23, 150, 156, 150, 163, 161, 162, 150, 157, 150, + 150, 150, 150, 165, 165, 159, 159, 166, 164, 28, + 29, 30, 31, 32, 45, 33, 34, 35, 36, 37, + 38, 39, 40, 41, 43, 42, 44, 46, 53, 54, + 155, 17, 0, 50, 18, 19, 20, 155, 155, 155, + 0, 155, 155, 0, 170, 0, 155, 0, 155, 58, + 0, 76, 76, 155, 155, 155, 0, 155, 155, 0, + 155, 155, 0, 155, 0, 16, 51, 21, 22, 47, + 155, 81, 82, 84, 85, 83, 153, 96, 48, 49, + 80, 150, 155, 56, 57, 61, 0, 63, 64, 65, + 66, 68, 67, 70, 69, 62, 158, 155, 75, 155, + 79, 78, 90, 94, 91, 92, 138, 93, 71, 72, + 86, 88, 89, 87, 52, 153, 98, 0, 59, 0, + 55, 137, 77, 73, 74, 97, 95, 151, 150, 150, + 150, 158, 158, 159, 159, 159, 149, 148, 148, 148, + 148, 148, 148, 158, 167, 101, 102, 111, 99, 100, + 109, 110, 119, 120, 103, 105, 104, 106, 107, 108, + 112, 113, 114, 115, 116, 117, 118, 60, 0, 155, + 155, 155, 155, 155, 155, 155, 155, 155, 0, 155, + 0, 155, 155, 155, 155, 155, 155, 155, 0, 124, + 155, 123, 125, 122, 131, 132, 135, 134, 136, 139, + 140, 141, 147, 142, 143, 144, 145, 146, 133, 126, + 128, 129, 130, 127, 121, 0, 0 }; -static const short yydefgoto[] = { 1, - 2, 3, 6, 11, 12, 34, 35, 36, 61, 53, - 80, 37, 85, 38, 97, 98, 134, 99, 64, 110, - 39, 76, 40, 41, 112, 113, 42, 43, 44, 45, - 46, 57, 90, 47, 78, 128, 48, 49, 50, 51, - 70, 52, 59, 131, 132, 163, 164, 165, 166, 203, - 167, 168, 200, 225, 169, 170, 171, 172, 173, 100, - 73, 174, 190, 175, 176, 177, 178, 179, 180, 192, - 193, 191, 54, 182, 4, 133, 13, 81, 55, 65, - 101, 74, 7, 60, 62, 58, 79, 71, 77, 201 +static const short yydefgoto[] = { 2, + 3, 4, 14, 15, 30, 31, 32, 33, 34, 35, + 36, 37, 5, 6, 11, 38, 39, 70, 71, 72, + 107, 43, 92, 73, 91, 74, 143, 144, 179, 145, + 110, 156, 75, 122, 76, 77, 158, 159, 78, 79, + 80, 81, 82, 103, 136, 83, 124, 174, 84, 85, + 86, 87, 116, 88, 105, 176, 177, 209, 210, 211, + 212, 251, 213, 214, 248, 274, 215, 216, 217, 218, + 219, 220, 146, 119, 221, 238, 222, 223, 224, 225, + 226, 227, 240, 241, 239, 44, 229, 7, 178, 40, + 93, 42, 111, 147, 120, 12, 106, 108, 104, 125, + 117, 123, 249, 8, 21, 9, 22, 16 }; -static const short yypact[] = {-32768, - 11,-32768,-32768, 9,-32768, -54, 15,-32768,-32768,-32768, - -40,-32768, 146,-32768,-32768,-32768,-32768,-32768,-32768,-32768, +static const short yypact[] = { -51, +-32768, 11,-32768,-32768,-32768,-32768, 8,-32768, -39,-32768, +-32768, 48,-32768, -19,-32768, 41,-32768,-32768,-32768,-32768, +-32768, -10,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768, +-32768,-32768,-32768,-32768,-32768,-32768,-32768, -19,-32768, 200, +-32768, 25,-32768, 59,-32768,-32768,-32768, 25, 25,-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,-32768,-32768,-32768,-32768,-32768, --32768,-32768,-32768, 19, 17,-32768,-32768, 40, -35, 24, --32768, 37,-32768, -1, 66, 3, 3,-32768,-32768,-32768, - 44,-32768,-32768, 54,-32768,-32768, 56,-32768, 0,-32768, - 13,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768, +-32768,-32768, -2,-32768,-32768,-32768,-32768,-32768,-32768,-32768, + 25,-32768,-32768, 38,-32768, 63,-32768, 70,-32768, 10, + -4, 17, 17,-32768,-32768,-32768, 73,-32768,-32768, 75, +-32768,-32768, 76,-32768, 4,-32768,-32768,-32768,-32768,-32768, -32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768, - 60,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768, +-32768,-32768,-32768,-32768,-32768,-32768, 77,-32768,-32768,-32768, -32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768, -32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768, - 16,-32768, 29,-32768, 72,-32768,-32768,-32768,-32768,-32768, +-32768,-32768,-32768,-32768,-32768, -19,-32768, 86,-32768, 79, -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,-32768,-32768,-32768,-32768, --32768, 73,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768, - 74,-32768, 75,-32768,-32768,-32768,-32768,-32768,-32768,-32768, - -49,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768, +-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768, 80,-32768, +-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768, 82,-32768, + 83,-32768,-32768,-32768,-32768,-32768,-32768,-32768, -25,-32768, -32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768, --32768,-32768,-32768,-32768,-32768,-32768, 82,-32768 +-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768, +-32768,-32768,-32768,-32768,-32768, 84,-32768 }; static const short yypgoto[] = {-32768, - 83,-32768,-32768,-32768, 84,-32768, -50,-32768,-32768, 6, - -56, -39,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768, --32768,-32768,-32768,-32768, 26,-32768,-32768,-32768,-32768, -37, + 87,-32768,-32768, 78,-32768,-32768,-32768,-32768,-32768,-32768, +-32768,-32768,-32768,-32768,-32768,-32768, 52,-32768, -87,-32768, +-32768, -22, -45, -82, -36,-32768,-32768,-32768,-32768,-32768, +-32768,-32768,-32768,-32768,-32768,-32768, -16,-32768,-32768,-32768, +-32768, -79,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768, +-32768,-32768, 36,-32768,-32768,-32768, -66,-32768,-32768,-32768, -32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768, - 68,-32768,-32768,-32768, -33,-32768,-32768,-32768,-32768,-32768, --32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768, -108, - -29,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768, -109, --32768,-32768, 4,-32768,-32768,-32768,-32768,-32768,-32768,-32768, --32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768 +-32768,-32768, -148, -60,-32768,-32768,-32768,-32768,-32768,-32768, +-32768,-32768, -174,-32768,-32768, -31,-32768,-32768,-32768,-32768, +-32768, -5,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768, +-32768,-32768,-32768, -3, -32,-32768,-32768,-32768 }; -#define YYLAST 199 - - -static const short yytable[] = { 86, - 87, 75, 138, -136, 93, 9, 95, 222, 223, 224, - 227, 115, 116, 117, 8, 119, 120, 10, 122, 123, - 14, 125, 82, 56, 91, 96, 92, 63, 130, 66, - 67, 68, 69, 83, 84, 16, 17, 18, 186, 187, - 136, 94, 143, 194, 195, 196, 197, 198, 118, 199, - 88, 89, 111, 126, 127, 139, 144, 140, 121, 145, - 124, 146, 147, 148, 137, 149, 150, 151, 152, 153, - 154, 155, 156, 157, 129, 181, 141, 202, 212, 214, - 158, 228, 160, 5, 159, 102, 103, 104, 105, 106, - 107, 108, 114, 161, 15, 162, 72, 142, 0, 135, +#define YYLAST 254 + + +static const short yytable[] = { 95, + 96, 97, 45, 46, 47, 51, 121, 18, 183, 1, + 276, 98, 99, 13, -158, 148, 149, 150, 151, 152, + 153, 154, 48, 49, 242, 243, 244, 245, 246, 100, + 17, 102, 271, 272, 273, 109, 142, 112, 113, 114, + 115, 89, 90, 233, 234, 126, 155, 101, 134, 135, + 19, -171, 128, 129, 130, 247, 132, 133, 172, 173, + 41, 139, 94, 141, 131, 138, 127, 157, 161, 162, + 163, 1, 165, 166, 140, 168, 169, 164, 171, 167, + 170, 182, 228, 277, 250, 175, 261, 263, 10, 50, + 206, 20, 52, 53, 54, 207, 160, 181, 208, 188, + 118, 137, 23, 24, 25, 26, 27, 28, 29, 186, + 180, 0, 184, 189, 185, 0, 190, 0, 191, 192, + 193, 0, 194, 195, 196, 197, 198, 199, 200, 201, + 202, 203, 0, 235, 236, 237, 0, 0, 204, 0, + 0, 0, 205, 187, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 230, 231, 232, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 109, 0, 0, 0, 188, - 189, 0, 0, 0, 0, 0, 204, 205, 206, 207, - 208, 209, 210, 211, 0, 213, 0, 215, 216, 217, - 218, 219, 220, 221, 0, 0, 226, 0, 0, 183, - 184, 185, 16, 17, 18, 19, 0, 0, 20, 0, - 21, 22, 0, 0, 23, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 24, 25, 0, 26, 0, 0, - 0, 27, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 28, 29, 30, 31, 0, 32, 0, 33 + 0, 0, 0, 0, 252, 253, 254, 255, 256, 257, + 258, 259, 260, 0, 262, 0, 264, 265, 266, 267, + 268, 269, 270, 0, 0, 275, 52, 53, 54, 55, + 0, 0, 56, 0, 57, 58, 0, 0, 59, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 60, 61, + 0, 62, 0, 0, 0, 63, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 64, 65, 66, 67, + 0, 68, 0, 69 }; -static const short yycheck[] = { 56, - 57, 31, 111, 5, 61, 60, 63, 57, 58, 59, - 0, 68, 69, 70, 6, 72, 73, 3, 75, 76, - 61, 78, 4, 18, 60, 27, 3, 22, 85, 24, - 25, 26, 27, 17, 18, 7, 8, 9, 147, 148, - 97, 5, 14, 153, 154, 155, 156, 157, 5, 158, - 11, 12, 50, 54, 55, 112, 28, 114, 5, 31, - 5, 33, 34, 35, 5, 37, 38, 39, 40, 41, - 42, 43, 44, 45, 62, 4, 61, 5, 5, 5, - 52, 0, 133, 1, 56, 20, 21, 22, 23, 24, - 25, 26, 67, 133, 11, 133, 29, 131, -1, 96, +static const short yycheck[] = { 45, + 46, 47, 25, 26, 27, 38, 67, 11, 157, 61, + 0, 48, 49, 6, 5, 20, 21, 22, 23, 24, + 25, 26, 28, 29, 199, 200, 201, 202, 203, 52, + 70, 54, 58, 59, 60, 58, 27, 60, 61, 62, + 63, 17, 18, 192, 193, 91, 51, 53, 11, 12, + 3, 71, 98, 99, 100, 204, 102, 103, 55, 56, + 71, 107, 4, 109, 101, 3, 69, 51, 114, 115, + 116, 61, 118, 119, 5, 121, 122, 5, 124, 5, + 5, 5, 4, 0, 5, 131, 5, 5, 2, 38, + 178, 14, 7, 8, 9, 178, 113, 143, 178, 14, + 65, 105, 62, 63, 64, 65, 66, 67, 68, 176, + 142, -1, 158, 28, 160, -1, 31, -1, 33, 34, + 35, -1, 37, 38, 39, 40, 41, 42, 43, 44, + 45, 46, -1, 194, 195, 196, -1, -1, 53, -1, + -1, -1, 57, 176, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 50, -1, -1, -1, 149, - 150, -1, -1, -1, -1, -1, 183, 184, 185, 186, - 187, 188, 189, 190, -1, 192, -1, 194, 195, 196, - 197, 198, 199, 200, -1, -1, 203, -1, -1, 144, - 145, 146, 7, 8, 9, 10, -1, -1, 13, -1, - 15, 16, -1, -1, 19, -1, -1, -1, -1, -1, - -1, -1, -1, -1, 29, 30, -1, 32, -1, -1, - -1, 36, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 46, 47, 48, 49, -1, 51, -1, 53 + -1, -1, -1, -1, -1, -1, 189, 190, 191, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 230, 231, 232, 233, 234, 235, + 236, 237, 238, -1, 240, -1, 242, 243, 244, 245, + 246, 247, 248, -1, -1, 251, 7, 8, 9, 10, + -1, -1, 13, -1, 15, 16, -1, -1, 19, -1, + -1, -1, -1, -1, -1, -1, -1, -1, 29, 30, + -1, 32, -1, -1, -1, 36, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 47, 48, 49, 50, + -1, 52, -1, 54 }; /* -*-C-*- Note some compilers choke on comments on `#line' lines. */ #line 3 "/usr/share/bison.simple" @@ -1073,8 +1133,50 @@ yyreduce: switch (yyn) { -case 3: -#line 170 "parser.y" +case 16: +#line 212 "parser.y" +{ + opt.log_activity = lastnr; + ; + break;} +case 17: +#line 220 "parser.y" +{ + opt.tcp_bufsz = lastnr; + ; + break;} +case 18: +#line 228 "parser.y" +{ + opt.dns_cachettl = lastnr; + ; + break;} +case 19: +#line 236 "parser.y" +{ + opt.log_facility = lastnr; + ; + break;} +case 20: +#line 244 "parser.y" +{ + opt.shmperm = lastnr; + ; + break;} +case 21: +#line 253 "parser.y" +{ + opt.sloppyportbind = lastnr; + ; + break;} +case 22: +#line 262 "parser.y" +{ + opt.leave_proctitle = lastnr; + ; + break;} +case 23: +#line 272 "parser.y" { /* Check integrity, supply defaults */ check_service (cur_service); @@ -1093,206 +1195,213 @@ case 3: memset (&cur_service, 0, sizeof(Service)); ; break;} -case 5: -#line 196 "parser.y" +case 25: +#line 298 "parser.y" { - psmsg ("service:", SYMBOL); + pmsg ("service [%s]\n", SYMBOL); for (i = 0; i < nservice; i++) if (!strcmp (service[i].name, SYMBOL)) error ("Duplicate definition of service '%s'", SYMBOL); cur_service.name = xstrdup(SYMBOL); ; break;} -case 9: -#line 218 "parser.y" +case 29: +#line 320 "parser.y" { - pimsg ("sevice port:", yyvsp[0].set[0].v.ival); + pmsg ("sevice port [%d]\n", yyvsp[0].set[0].v.ival); cur_service.port = yyvsp[0].set[0].v.ival; free (yyvsp[0].set); ; break;} -case 10: -#line 224 "parser.y" +case 30: +#line 326 "parser.y" { - psmsg ("service binding:", yyvsp[0].set[0].v.sval); + pmsg ("service binding [%s]\n", yyvsp[0].set[0].v.sval); cur_service.bind = yyvsp[0].set[0].v.sval; free (yyvsp[0].set); ; break;} -case 11: -#line 230 "parser.y" +case 31: +#line 332 "parser.y" { - pimsg ("service verbosity:", yyvsp[0].set[0].v.ival); + pmsg ("service verbosity [%d]\n", yyvsp[0].set[0].v.ival); cur_service.verbosity = yyvsp[0].set[0].v.ival; free (yyvsp[0].set); ; break;} -case 12: -#line 236 "parser.y" +case 32: +#line 338 "parser.y" { - pimsg ("service dispatch mode:", yyvsp[0].set[0].v.ival); - pimsg ("service dispatch over:", lastovernr); - psmsg ("service dispatch exth:", lastext); + pmsg ("service dispatch mode [%d]\n", yyvsp[0].set[0].v.ival); + pmsg ("service dispatch over [%d]\n", lastovernr); + pmsg ("service dispatch exthandler [%s]\n", lastext); cur_service.dispatchtype = yyvsp[0].set[0].v.ival; cur_service.dispatchover = lastovernr; - cur_service.dispatchext = lastext; + cur_service.dispatchext = xstrdup(lastext); free (yyvsp[0].set); ; break;} -case 13: -#line 246 "parser.y" +case 33: +#line 348 "parser.y" { - pimsg ("service revival interval:", yyvsp[0].set[0].v.ival); - psmsg ("service revival cmd:", yyvsp[0].set[1].v.sval); + pmsg ("service revival interval [%d]\n", yyvsp[0].set[0].v.ival); + pmsg ("service revival cmd [%s]\n", yyvsp[0].set[1].v.sval); cur_service.rev_interval = yyvsp[0].set[0].v.ival; cur_service.check_cmd = yyvsp[0].set[1].v.sval; free (yyvsp[0].set); ; break;} -case 14: -#line 254 "parser.y" +case 34: +#line 356 "parser.y" { - pimsg ("service check interval:", yyvsp[0].set[0].v.ival); - psmsg ("service check cmd:", yyvsp[0].set[1].v.sval); + pmsg ("service check interval [%d]\n", yyvsp[0].set[0].v.ival); + pmsg ("service check cmd [%s]\n", yyvsp[0].set[1].v.sval); cur_service.check_interval = yyvsp[0].set[0].v.ival; cur_service.check_cmd = yyvsp[0].set[1].v.sval; ; break;} -case 15: -#line 261 "parser.y" +case 35: +#line 363 "parser.y" { - pimsg ("service backlog:", yyvsp[0].set[0].v.ival); + pmsg ("service backlog [%d]\n", yyvsp[0].set[0].v.ival); cur_service.backlog = yyvsp[0].set[0].v.ival; free (yyvsp[0].set); ; break;} -case 16: -#line 267 "parser.y" +case 36: +#line 369 "parser.y" { - pimsg ("service shmkey:", yyvsp[0].set[0].v.ival); + pmsg ("service shmkey [%d]\n", yyvsp[0].set[0].v.ival); cur_service.shmkey = yyvsp[0].set[0].v.ival; free (yyvsp[0].set); ; break;} -case 17: -#line 273 "parser.y" +case 37: +#line 375 "parser.y" { - pimsg ("connection timout:", yyvsp[0].set[0].v.ival); + pmsg ("connection timout [%d]\n", yyvsp[0].set[0].v.ival); cur_service.connectiontimeout = yyvsp[0].set[0].v.ival; free (yyvsp[0].set); ; break;} -case 18: -#line 279 "parser.y" +case 38: +#line 381 "parser.y" { - pimsg ("max clients in service:", yyvsp[0].set[0].v.ival); + pmsg ("max clients in service [%d]\n", yyvsp[0].set[0].v.ival); cur_service.maxconnections = yyvsp[0].set[0].v.ival; free (yyvsp[0].set); ; break;} -case 19: -#line 285 "parser.y" +case 39: +#line 387 "parser.y" { - pimsg ("service type: ", yyvsp[0].set[0].v.ival); + pmsg ("service type [%d]\n", yyvsp[0].set[0].v.ival); cur_service.type = yyvsp[0].set[0].v.ival; free (yyvsp[0].set); ; break;} -case 20: -#line 291 "parser.y" +case 40: +#line 393 "parser.y" { - pimsg ("service header inspection: ", yyvsp[0].set[0].v.ival); + pmsg ("service header inspection [%d]\n", yyvsp[0].set[0].v.ival); cur_service.inspection = yyvsp[0].set[0].v.ival; free (yyvsp[0].set); ; break;} -case 21: -#line 297 "parser.y" +case 41: +#line 399 "parser.y" { - psmsg ("allow from: ", yyvsp[0].set[0].v.sval); + pmsg ("allow from [%s]\n", yyvsp[0].set[0].v.sval); add_allowfrom (yyvsp[0].set[0].v.sval); free (yyvsp[0].set); ; break;} -case 22: -#line 303 "parser.y" +case 42: +#line 405 "parser.y" { - psmsg ("allow file: ", yyvsp[0].set[0].v.sval); + pmsg ("allow file [%s]\n", yyvsp[0].set[0].v.sval); cur_service.allowfile = yyvsp[0].set[0].v.sval; free (yyvsp[0].set); ; break;} -case 23: -#line 309 "parser.y" +case 43: +#line 411 "parser.y" { - psmsg ("deny from: ", yyvsp[0].set[0].v.sval); + pmsg ("deny from [%s]\n", yyvsp[0].set[0].v.sval); add_denyfrom (yyvsp[0].set[0].v.sval); free (yyvsp[0].set); ; break;} -case 24: -#line 315 "parser.y" +case 44: +#line 417 "parser.y" { - psmsg ("deny file: ", yyvsp[0].set[0].v.sval); + pmsg ("deny file [%s]\n", yyvsp[0].set[0].v.sval); cur_service.denyfile = yyvsp[0].set[0].v.sval; free (yyvsp[0].set); ; break;} -case 25: -#line 321 "parser.y" +case 45: +#line 423 "parser.y" { - psmsg ("user account: ", yyvsp[0].set[0].v.sval); + pmsg ("user account [%s]\n", 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 26: -#line 328 "parser.y" +case 46: +#line 430 "parser.y" { - pimsg ("converting backend statements, count is", yyvsp[0].n); + pmsg ("converting backend statements, count is [%d]\n", yyvsp[0].n); for (i = 0; i < yyvsp[0].n; i++) switch (yyvsp[0].set[i].cf) { case cf_portspec: - pimsg ("backend block port:", yyvsp[0].set[i].v.ival); + pmsg ("backend port [%d]\n", yyvsp[0].set[i].v.ival); cur_backend.initial_port = yyvsp[0].set[i].v.ival; break; case cf_serverspec: - psmsg ("backend block server:", yyvsp[0].set[i].v.sval); + pmsg ("backend server [%s]\n", yyvsp[0].set[i].v.sval); cur_backend.initial_server = serverpart (yyvsp[0].set[i].v.sval); cur_backend.initial_port = portpart (yyvsp[0].set[i].v.sval); free (yyvsp[0].set[i].v.sval); break; case cf_verbosityspec: - pimsg ("backend block verbosity:", yyvsp[0].set[i].v.ival); + pmsg ("backend verbosity [%d]\n", yyvsp[0].set[i].v.ival); cur_backend.verbosity = yyvsp[0].set[i].v.ival; break; case cf_onstartspec: - psmsg ("backend block onstart:", yyvsp[0].set[i].v.sval); + pmsg ("backend onstart [%s]\n", yyvsp[0].set[i].v.sval); cur_backend.onstart = yyvsp[0].set[i].v.sval; break; case cf_onfailspec: - psmsg ("backend block onfail:", yyvsp[0].set[i].v.sval); + pmsg ("backend onfail [%s]\n", yyvsp[0].set[i].v.sval); cur_backend.onfail = yyvsp[0].set[i].v.sval; break; case cf_onendspec: - psmsg ("backend block onend:", yyvsp[0].set[i].v.sval); + pmsg ("backend onend [%s]\n", yyvsp[0].set[i].v.sval); cur_backend.onend = yyvsp[0].set[i].v.sval; break; case cf_dumpspec: - psmsg ("backend trafficlog:", yyvsp[0].set[i].v.sval); + pmsg ("backend trafficlog [%s]\n", yyvsp[0].set[i].v.sval); cur_backend.dumpfile = yyvsp[0].set[i].v.sval; break; case cf_thruspec: - psmsg ("backend throughputlog:", yyvsp[0].set[i].v.sval); + pmsg ("backend throughputlog [%s]\n", yyvsp[0].set[i].v.sval); cur_backend.thruputfile = yyvsp[0].set[i].v.sval; break; + case cf_httptimingspec: + if (cur_service.type != type_http) + error ("'httptiminglog' only allowed in 'type http' " + "service definitions"); + pmsg ("backend http timing log [%s]\n", yyvsp[0].set[i].v.sval); + cur_backend.timinglog = yyvsp[0].set[i].v.sval; + break; case cf_weightspec: - pimsg ("backend weight:", yyvsp[0].set[i].v.ival); + pmsg ("backend weight [%d]\n", yyvsp[0].set[i].v.ival); cur_backend.weight = yyvsp[0].set[i].v.ival; break; case cf_decayspec: - pimsg ("backend decay:", yyvsp[0].set[i].v.ival); + pmsg ("backend decay [%d]\n", yyvsp[0].set[i].v.ival); if (yyvsp[0].set[i].v.ival >= 100) error ("Decay specifier %d must be a percentage, " "never more than 99", @@ -1300,17 +1409,17 @@ case 26: cur_backend.decay = yyvsp[0].set[i].v.ival; break; case cf_maxconnectionsspec: - pimsg ("backend max clients: ", yyvsp[0].set[i].v.ival); + pmsg ("backend max clients [%d]\n", yyvsp[0].set[i].v.ival); cur_backend.maxconnections = yyvsp[0].set[i].v.ival; break; case cf_stickycookiespec: - psmsg ("backend sticky cookie:", - yyvsp[0].set[i].v.sval); + pmsg ("backend sticky cookie [%s]\n", + yyvsp[0].set[i].v.sval); cur_backend.stickycookie = yyvsp[0].set[i].v.sval; break; case cf_addclientheaderspec: - psmsg ("client header to add:", - yyvsp[0].set[i].v.sval); + pmsg ("client header to add [%s]\n", + yyvsp[0].set[i].v.sval); cur_backend.addclientheader = xrealloc (cur_backend.addclientheader, (cur_backend.naddclientheader + 1) * @@ -1320,8 +1429,8 @@ case 26: yyvsp[0].set[i].v.sval; break; case cf_setclientheaderspec: - psmsg ("client header to set:", - yyvsp[0].set[i].v.sval); + pmsg ("client header to set [%s]\n", + yyvsp[0].set[i].v.sval); cur_backend.setclientheader = xrealloc (cur_backend.setclientheader, (cur_backend.nsetclientheader + 1) * @@ -1331,8 +1440,8 @@ case 26: yyvsp[0].set[i].v.sval; break; case cf_appendclientheaderspec: - psmsg ("client header to append:", - yyvsp[0].set[i].v.sval); + pmsg ("client header to append [%s]\n", + yyvsp[0].set[i].v.sval); cur_backend.appendclientheader = xrealloc (cur_backend.appendclientheader, (cur_backend.nappendclientheader + 1) * @@ -1342,8 +1451,8 @@ case 26: yyvsp[0].set[i].v.sval; break; case cf_addserverheaderspec: - psmsg ("server header to add:", - yyvsp[0].set[i].v.sval); + pmsg ("server header to add [%s]\n", + yyvsp[0].set[i].v.sval); cur_backend.addserverheader = xrealloc (cur_backend.addserverheader, (cur_backend.naddserverheader + 1) * @@ -1353,8 +1462,8 @@ case 26: yyvsp[0].set[i].v.sval; break; case cf_setserverheaderspec: - psmsg ("server header to set:", - yyvsp[0].set[i].v.sval); + pmsg ("server header to set [%s]\n", + yyvsp[0].set[i].v.sval); cur_backend.setserverheader = xrealloc (cur_backend.setserverheader, (cur_backend.nsetserverheader + 1) * @@ -1364,8 +1473,8 @@ case 26: yyvsp[0].set[i].v.sval; break; case cf_appendserverheaderspec: - psmsg ("server header to append:", - yyvsp[0].set[i].v.sval); + pmsg ("server header to append:", + yyvsp[0].set[i].v.sval); cur_backend.appendserverheader = xrealloc (cur_backend.appendserverheader, (cur_backend.nappendserverheader + 1) * @@ -1375,11 +1484,11 @@ case 26: yyvsp[0].set[i].v.sval; break; case cf_retriesspec: - pimsg ("backend retries:", yyvsp[0].set[i].v.ival); + pmsg ("backend retries [%d]\n", yyvsp[0].set[i].v.ival); cur_backend.retries = yyvsp[0].set[i].v.ival; break; case cf_statespec: - pimsg ("backend initial state:", yyvsp[0].set[i].v.ival); + pmsg ("backend initial state [%d]\n", yyvsp[0].set[i].v.ival); cur_backend.initial_avail = yyvsp[0].set[i].v.ival; break; default: @@ -1399,6 +1508,7 @@ case 26: cur_backend.weight = 1; if (cur_backend.retries < 1) cur_backend.retries = 1; + /* if (! cur_backend.onstart) cur_backend.onstart = xstrdup (""); if (! cur_backend.onfail) @@ -1407,93 +1517,96 @@ case 26: cur_backend.onend = xstrdup (""); if (! cur_backend.thruputfile) cur_backend.thruputfile = xstrdup (""); + if (! cur_backend.timinglog) + cur_backend.timinglog = xstrdup (""); if (! cur_backend.dumpfile) cur_backend.dumpfile = xstrdup (""); if (! cur_backend.stickycookie) cur_backend.stickycookie = xstrdup (""); - + */ + /* Add to the list. */ cur_service.backend = xrealloc (cur_service.backend, ++cur_service.nbackend * sizeof(Backend)); cur_service.backend[cur_service.nbackend - 1] = cur_backend; - pimsg ("this was backend definition", cur_service.nbackend); + pmsg ("this was backend definition [%d]\n", cur_service.nbackend); memset (&cur_backend, 0, sizeof(cur_backend)); ; break;} -case 27: -#line 505 "parser.y" +case 47: +#line 618 "parser.y" { - pimsg ("port statement:", lastnr); + pmsg ("port statement [%d]\n", lastnr); yyval.n = 1; yyval.set = xmalloc (sizeof(Confset)); yyval.set[0].cf = cf_portspec; yyval.set[0].v.ival = lastnr; ; break;} -case 28: -#line 517 "parser.y" +case 48: +#line 630 "parser.y" { - psmsg ("bindto statement:", laststr); + pmsg ("bindto statement [%d]\n", laststr); yyval.n = 1; yyval.set = xmalloc (sizeof(Confset)); yyval.set[0].cf = cf_bindspec; yyval.set[0].v.sval = xstrdup(laststr); ; break;} -case 29: -#line 528 "parser.y" +case 49: +#line 641 "parser.y" { setlaststr (laststring); free (laststring); laststring = 0; ; break;} -case 30: -#line 537 "parser.y" +case 50: +#line 650 "parser.y" { setlastnr (SYMBOL); ; break;} -case 32: -#line 551 "parser.y" +case 52: +#line 664 "parser.y" { - pimsg ("verbosity statement:", lastnr); + pmsg ("verbosity statement [%d]\n", lastnr); yyval.n = 1; yyval.set = xmalloc (sizeof(Confset)); yyval.set[0].cf = cf_verbosityspec; yyval.set[0].v.ival = lastnr; ; break;} -case 33: -#line 561 "parser.y" +case 53: +#line 674 "parser.y" { lastnr = 1; ; break;} -case 34: -#line 565 "parser.y" +case 54: +#line 678 "parser.y" { lastnr = 0; ; break;} -case 35: -#line 574 "parser.y" +case 55: +#line 687 "parser.y" { yyval = yyvsp[-2]; ; break;} -case 38: -#line 584 "parser.y" +case 58: +#line 697 "parser.y" { yyval.n = 0; ; break;} -case 39: -#line 591 "parser.y" +case 59: +#line 704 "parser.y" { - pimsg ("dispatch mode statement:", lastnr); + pmsg ("dispatch mode statement [%d]\n", lastnr); yyval.n = 1; yyval.set = xmalloc (sizeof(Confset)); yyval.set[0].cf = cf_dispatchspec; @@ -1506,282 +1619,282 @@ case 39: cur_service.name); ; break;} -case 40: -#line 608 "parser.y" +case 60: +#line 721 "parser.y" { setlastovernr (SYMBOL); ; break;} -case 41: -#line 614 "parser.y" +case 61: +#line 727 "parser.y" { - psmsg ("external handler:", laststr); + pmsg ("external handler [%s]\n", laststr); if (lastnr != ds_externalhandler) error ("Service %s: this dispatch mode doesn't support " "an external handler", cur_service.name); setlastext (laststr); ; break;} -case 42: -#line 625 "parser.y" +case 62: +#line 738 "parser.y" { yyval.n = 1; yyval.set = xmalloc (sizeof(Confset)); yyval.set[0].v.ival = lastnr; ; break;} -case 43: -#line 633 "parser.y" +case 63: +#line 746 "parser.y" { lastnr = ds_roundrobin; ; break;} -case 44: -#line 637 "parser.y" +case 64: +#line 750 "parser.y" { lastnr = ds_random; ; break;} -case 45: -#line 641 "parser.y" +case 65: +#line 754 "parser.y" { lastnr = ds_byduration; ; break;} -case 46: -#line 645 "parser.y" +case 66: +#line 758 "parser.y" { lastnr = ds_bysize; ; break;} -case 47: -#line 649 "parser.y" +case 67: +#line 762 "parser.y" { lastnr = ds_byorder; ; break;} -case 48: -#line 653 "parser.y" +case 68: +#line 766 "parser.y" { lastnr = ds_byconnections; ; break;} -case 49: -#line 657 "parser.y" +case 69: +#line 770 "parser.y" { lastnr = ds_externalhandler; ; break;} -case 50: -#line 661 "parser.y" +case 70: +#line 774 "parser.y" { lastnr = ds_byclientip; ; break;} -case 51: -#line 669 "parser.y" +case 71: +#line 782 "parser.y" { - psmsg ("user account statement:", laststr); + pmsg ("user account statement [%d]\n", laststr); yyval.n = 1; yyval.set = xmalloc (sizeof(Confset)); yyval.set[0].cf = cf_useraccountspec; yyval.set[0].v.sval = xstrdup (laststr); ; break;} -case 52: -#line 680 "parser.y" +case 72: +#line 793 "parser.y" { setlaststr (laststring); free (laststring); laststring = 0; ; break;} -case 53: -#line 691 "parser.y" +case 73: +#line 804 "parser.y" { - pimsg ("reviving interval statement:", lastnr); + pmsg ("reviving interval statement [%d]\n", lastnr); yyval.n = 2; yyval.set = xmalloc (2 * sizeof(Confset)); yyval.set[0].cf = cf_revivespec; yyval.set[0].v.ival = lastnr; if (yyvsp[-1].n) { - psmsg ("reviving externalhandler:", yyvsp[-1].set[0].v.sval); + pmsg ("reviving externalhandler [%s]\n", yyvsp[-1].set[0].v.sval); yyval.set[1].v.sval = yyvsp[-1].set[0].v.sval; } else yyval.set[1].v.sval = 0; ; break;} -case 54: -#line 709 "parser.y" +case 74: +#line 822 "parser.y" { - pimsg ("check interval:", lastnr); + pmsg ("check interval [%d]\n", lastnr); yyval.n = 2; yyval.set = xmalloc (2 * sizeof(Confset)); yyval.set[0].cf = cf_checkspec; yyval.set[0].v.ival = lastnr; if (yyvsp[-1].n) { - psmsg ("check externalhandler:", yyvsp[-1].set[0].v.sval); + pmsg ("check externalhandler [%s]\n", yyvsp[-1].set[0].v.sval); yyval.set[1].v.sval = yyvsp[-1].set[0].v.sval; } else yyval.set[1].v.sval = 0; ; break;} -case 56: -#line 726 "parser.y" +case 76: +#line 839 "parser.y" { yyval.n = 0; ; break;} -case 57: -#line 733 "parser.y" +case 77: +#line 846 "parser.y" { yyval.n = 1; yyval.set = xmalloc (sizeof(Confset)); yyval.set[0].v.sval = xstrdup (laststr); ; break;} -case 58: -#line 743 "parser.y" +case 78: +#line 856 "parser.y" { - pimsg ("backlog statement:", lastnr); + pmsg ("backlog statement [%d]\n", lastnr); yyval.n = 1; yyval.set = xmalloc (sizeof(Confset)); yyval.set[0].cf = cf_backlogspec; yyval.set[0].v.ival = lastnr; ; break;} -case 59: -#line 755 "parser.y" +case 79: +#line 868 "parser.y" { - pimsg ("shmkey statement:", lastnr); + pmsg ("shmkey statement [%d]\n", lastnr); yyval.n = 1; yyval.set = xmalloc (sizeof(Confset)); yyval.set[0].cf = cf_shmkeyspec; yyval.set[0].v.ival = lastnr; ; break;} -case 60: -#line 767 "parser.y" +case 80: +#line 880 "parser.y" { - pimsg ("connection timeout statement:", lastnr); + pmsg ("connection timeout statement [%d]\n", lastnr); yyval.n = 1; yyval.set = xmalloc (sizeof(Confset)); yyval.set[0].cf = cf_connectiontimeoutspec; yyval.set[0].v.ival = lastnr; ; break;} -case 61: -#line 779 "parser.y" +case 81: +#line 892 "parser.y" { - pimsg ("max clients statement (service):", lastnr); + pmsg ("max clients statement (service) [%d]\n", lastnr); yyval.n = 1; yyval.set = xmalloc (sizeof(Confset)); yyval.set[0].cf = cf_maxconnectionsspec; yyval.set[0].v.ival = lastnr; ; break;} -case 62: -#line 791 "parser.y" +case 82: +#line 904 "parser.y" { - pimsg ("service type:", lastnr); + pmsg ("service type [%d]\n", lastnr); yyval.n = 1; yyval.set = xmalloc (sizeof(Confset)); yyval.set[0].cf = cf_typespec; yyval.set[0].v.ival = lastnr; ; break;} -case 64: -#line 806 "parser.y" +case 84: +#line 919 "parser.y" { lastnr = type_any; ; break;} -case 65: -#line 810 "parser.y" +case 85: +#line 923 "parser.y" { lastnr = type_http; ; break;} -case 66: -#line 818 "parser.y" +case 86: +#line 931 "parser.y" { - pimsg ("service header inspection: ", lastnr); + pmsg ("service header inspection [%d]\n", lastnr); yyval.n = 1; yyval.set = xmalloc (sizeof(Confset)); yyval.set[0].cf = cf_inspectionspec; yyval.set[0].v.ival = lastnr; ; break;} -case 68: -#line 833 "parser.y" +case 88: +#line 946 "parser.y" { lastnr = ins_deep; ; break;} -case 69: -#line 837 "parser.y" +case 89: +#line 950 "parser.y" { lastnr = ins_shallow; ; break;} -case 70: -#line 845 "parser.y" +case 90: +#line 958 "parser.y" { - psmsg ("allow from: ", laststr); + pmsg ("allow from [%s]\n", laststr); yyval.n = 1; yyval.set = xmalloc (sizeof(Confset)); yyval.set[0].cf = cf_allowfromspec; yyval.set[0].v.sval = xstrdup(laststr); ; break;} -case 71: -#line 857 "parser.y" +case 91: +#line 970 "parser.y" { - psmsg ("allow from: ", laststr); + pmsg ("deny from [%s]\n", laststr); yyval.n = 1; yyval.set = xmalloc (sizeof(Confset)); yyval.set[0].cf = cf_denyfromspec; yyval.set[0].v.sval = xstrdup(laststr); ; break;} -case 72: -#line 869 "parser.y" +case 92: +#line 982 "parser.y" { - psmsg ("allow file: ", laststr); + pmsg ("allow file [%s]\n", laststr); yyval.n = 1; yyval.set = xmalloc (sizeof(Confset)); yyval.set[0].cf = cf_allowfilespec; yyval.set[0].v.sval = xstrdup(laststr); ; break;} -case 73: -#line 881 "parser.y" +case 93: +#line 994 "parser.y" { - psmsg ("allow file: ", laststr); + pmsg ("deny file [%s]\n", laststr); yyval.n = 1; yyval.set = xmalloc (sizeof(Confset)); yyval.set[0].cf = cf_allowfilespec; yyval.set[0].v.sval = xstrdup(laststr); ; break;} -case 74: -#line 892 "parser.y" +case 94: +#line 1005 "parser.y" { setlaststr (laststring); free (laststring); laststring = 0; ; break;} -case 75: -#line 904 "parser.y" +case 95: +#line 1017 "parser.y" { yyval = yyvsp[-1]; ; break;} -case 76: -#line 911 "parser.y" +case 96: +#line 1024 "parser.y" { - psmsg ("backend name:", SYMBOL); + pmsg ("backend name [%s]\n", SYMBOL); for (i = 0; i < cur_service.nbackend; i++) if (!strcmp (cur_service.backend[i].name, SYMBOL)) error ("Service %s: back end '%s' multiply defined", @@ -1789,8 +1902,8 @@ case 76: cur_backend.name = xstrdup (SYMBOL); ; break;} -case 77: -#line 923 "parser.y" +case 97: +#line 1036 "parser.y" { yyvsp[-1].n++; yyvsp[-1].set = xrealloc (yyvsp[-1].set, yyvsp[-1].n * sizeof(Confset)); @@ -1798,504 +1911,539 @@ case 77: yyval = yyvsp[-1]; ; break;} -case 78: -#line 930 "parser.y" +case 98: +#line 1043 "parser.y" { yyval = yyvsp[0]; ; break;} -case 79: -#line 937 "parser.y" +case 99: +#line 1050 "parser.y" { yyval = yyvsp[0]; ; break;} -case 80: -#line 943 "parser.y" +case 100: +#line 1056 "parser.y" { - psmsg ("backend server:", yyvsp[0].set[0].v.sval); + pmsg ("backend server [%s]\n", yyvsp[0].set[0].v.sval); yyval = yyvsp[0]; ; break;} -case 81: -#line 948 "parser.y" +case 101: +#line 1061 "parser.y" { - pimsg ("backend port:", yyvsp[0].set[0].v.ival); + pmsg ("backend port [%d]\n", yyvsp[0].set[0].v.ival); yyval = yyvsp[0]; ; break;} -case 82: -#line 953 "parser.y" +case 102: +#line 1066 "parser.y" { - pimsg ("backend verbosity:", yyvsp[0].set[0].v.ival); + pmsg ("backend verbosity [%d]\n", yyvsp[0].set[0].v.ival); yyval = yyvsp[0]; ; break;} -case 83: -#line 958 "parser.y" +case 103: +#line 1071 "parser.y" { - psmsg ("backend onstart:", yyvsp[0].set[0].v.sval); + pmsg ("backend onstart [%s]\n", yyvsp[0].set[0].v.sval); yyval = yyvsp[0]; ; break;} -case 84: -#line 963 "parser.y" +case 104: +#line 1076 "parser.y" { - psmsg ("backend onend:", yyvsp[0].set[0].v.sval); + pmsg ("backend onend [%s]\n", yyvsp[0].set[0].v.sval); yyval = yyvsp[0]; ; break;} -case 85: -#line 968 "parser.y" +case 105: +#line 1081 "parser.y" { - psmsg ("backend onfail:", yyvsp[0].set[0].v.sval); + pmsg ("backend onfail [%s]\n", yyvsp[0].set[0].v.sval); yyval = yyvsp[0]; ; break;} -case 86: -#line 973 "parser.y" +case 106: +#line 1086 "parser.y" { - psmsg ("backend trafficlog:", yyvsp[0].set[0].v.sval); + pmsg ("backend trafficlog [%s]\n", yyvsp[0].set[0].v.sval); yyval = yyvsp[0]; ; break;} -case 87: -#line 978 "parser.y" +case 107: +#line 1091 "parser.y" { - psmsg ("backend trafficlog:", yyvsp[0].set[0].v.sval); + pmsg ("backend trafficlog [%s]\n", yyvsp[0].set[0].v.sval); yyval = yyvsp[0]; ; break;} -case 88: -#line 983 "parser.y" +case 108: +#line 1096 "parser.y" { - pimsg ("backend weight:", yyvsp[0].set[0].v.ival); + pmsg ("backend HTTP timing log [%s]\n", yyvsp[0].set[0].v.sval); yyval = yyvsp[0]; ; break;} -case 89: -#line 988 "parser.y" +case 109: +#line 1101 "parser.y" { - pimsg ("backend decay:", yyvsp[0].set[0].v.ival); + pmsg ("backend weight [%d]\n", yyvsp[0].set[0].v.ival); yyval = yyvsp[0]; ; break;} -case 90: -#line 993 "parser.y" +case 110: +#line 1106 "parser.y" { - pimsg ("backend maxconnections:", yyvsp[0].set[0].v.ival); + pmsg ("backend decay [%d]\n", yyvsp[0].set[0].v.ival); yyval = yyvsp[0]; ; break;} -case 91: -#line 998 "parser.y" +case 111: +#line 1111 "parser.y" { - psmsg ("backend sticky cookie:", yyvsp[0].set[0].v.sval); + pmsg ("backend maxconnections [%d]\n", yyvsp[0].set[0].v.ival); yyval = yyvsp[0]; ; break;} -case 92: -#line 1003 "parser.y" +case 112: +#line 1116 "parser.y" { - psmsg ("addclientheader:", yyvsp[0].set[0].v.sval); + pmsg ("backend sticky cookie [%s]\n", yyvsp[0].set[0].v.sval); yyval = yyvsp[0]; ; break;} -case 93: -#line 1008 "parser.y" +case 113: +#line 1121 "parser.y" { - psmsg ("setclientheader:", yyvsp[0].set[0].v.sval); + pmsg ("addclientheader [%s]\n", yyvsp[0].set[0].v.sval); yyval = yyvsp[0]; ; break;} -case 94: -#line 1013 "parser.y" +case 114: +#line 1126 "parser.y" { - psmsg ("appendclientheader:", yyvsp[0].set[0].v.sval); + pmsg ("setclientheader [%s]\n", yyvsp[0].set[0].v.sval); yyval = yyvsp[0]; ; break;} -case 95: -#line 1018 "parser.y" +case 115: +#line 1131 "parser.y" { - psmsg ("addserverheader:", yyvsp[0].set[0].v.sval); + pmsg ("appendclientheader [%s]\n", yyvsp[0].set[0].v.sval); yyval = yyvsp[0]; ; break;} -case 96: -#line 1023 "parser.y" +case 116: +#line 1136 "parser.y" { - psmsg ("setserverheader:", yyvsp[0].set[0].v.sval); + pmsg ("addserverheader [%s]\n", yyvsp[0].set[0].v.sval); yyval = yyvsp[0]; ; break;} -case 97: -#line 1028 "parser.y" +case 117: +#line 1141 "parser.y" { - psmsg ("appendserverheader:", yyvsp[0].set[0].v.sval); + pmsg ("setserverheader [%s]\n", yyvsp[0].set[0].v.sval); yyval = yyvsp[0]; ; break;} -case 98: -#line 1033 "parser.y" +case 118: +#line 1146 "parser.y" { - pimsg ("backend retries:", yyvsp[0].set[0].v.ival); + pmsg ("appendserverheader [%s]\n", yyvsp[0].set[0].v.sval); yyval = yyvsp[0]; ; break;} -case 99: -#line 1038 "parser.y" +case 119: +#line 1151 "parser.y" { - pimsg ("backend state:", yyvsp[0].set[0].v.ival); + pmsg ("backend retries [%d]\n", yyvsp[0].set[0].v.ival); yyval = yyvsp[0]; ; break;} -case 100: -#line 1048 "parser.y" +case 120: +#line 1156 "parser.y" +{ + pmsg ("backend state [%d]\n", yyvsp[0].set[0].v.ival); + yyval = yyvsp[0]; + ; + break;} +case 121: +#line 1166 "parser.y" { - psmsg ("server statement:", laststr); + pmsg ("server statement [%s]\n", laststr); yyval.n = 1; yyval.set = xmalloc (sizeof (Confset)); yyval.set[0].cf = cf_serverspec; yyval.set[0].v.sval = xstrdup (laststr); ; break;} -case 101: -#line 1060 "parser.y" +case 122: +#line 1178 "parser.y" { - pimsg ("weight statement", lastnr); + pmsg ("weight statement [%d]\n", lastnr); yyval.n = 1; yyval.set = xmalloc (sizeof (Confset)); yyval.set[0].cf = cf_weightspec; yyval.set[0].v.ival = lastnr; ; break;} -case 102: -#line 1072 "parser.y" +case 123: +#line 1190 "parser.y" { - pimsg ("decay statement", lastnr); + pmsg ("decay statement [%d]\n", lastnr); yyval.n = 1; yyval.set = xmalloc (sizeof (Confset)); yyval.set[0].cf = cf_decayspec; yyval.set[0].v.ival = lastnr; ; break;} -case 103: -#line 1082 "parser.y" +case 124: +#line 1200 "parser.y" { setlaststr (laststring); ; break;} -case 104: -#line 1090 "parser.y" +case 125: +#line 1208 "parser.y" { - pimsg ("retries:", lastnr); + pmsg ("retries [%d]\n", lastnr); yyval.n = 1; yyval.set = xmalloc (sizeof(Confset)); yyval.set[0].cf = cf_retriesspec; yyval.set[0].v.ival = lastnr; ; break;} -case 105: -#line 1102 "parser.y" +case 126: +#line 1220 "parser.y" { - pimsg ("state:", lastnr); + pmsg ("state [%d]\n", lastnr); yyval.n = 1; yyval.set = xmalloc (sizeof(Confset)); yyval.set[0].cf = cf_statespec; yyval.set[0].v.ival = lastnr; ; break;} -case 107: -#line 1117 "parser.y" +case 128: +#line 1235 "parser.y" { lastnr = st_available; ; break;} -case 108: -#line 1121 "parser.y" +case 129: +#line 1239 "parser.y" { lastnr = st_unavailable; ; break;} -case 109: -#line 1125 "parser.y" +case 130: +#line 1243 "parser.y" { lastnr = st_down; ; break;} -case 110: -#line 1133 "parser.y" +case 131: +#line 1251 "parser.y" { - psmsg ("onstart statement:", laststr); + pmsg ("onstart statement [%s]\n", laststr); yyval.n = 1; yyval.set = xmalloc (sizeof (Confset)); yyval.set[0].cf = cf_onstartspec; yyval.set[0].v.sval = xstrdup (laststr); ; break;} -case 111: -#line 1145 "parser.y" +case 132: +#line 1263 "parser.y" { - psmsg ("onfail statement:", laststr); + pmsg ("onfail statement [%s]\n", laststr); yyval.n = 1; yyval.set = xmalloc (sizeof (Confset)); yyval.set[0].cf = cf_onfailspec; yyval.set[0].v.sval = xstrdup (laststr); ; break;} -case 112: -#line 1157 "parser.y" +case 133: +#line 1275 "parser.y" { - psmsg ("onend statement:", laststr); + pmsg ("onend statement [%s]\n", laststr); yyval.n = 1; yyval.set = xmalloc (sizeof (Confset)); yyval.set[0].cf = cf_onendspec; yyval.set[0].v.sval = xstrdup (laststr); ; break;} -case 113: -#line 1169 "parser.y" +case 134: +#line 1287 "parser.y" { - psmsg ("trafficlog statement:", laststr); + pmsg ("trafficlog statement [%s]\n", laststr); yyval.n = 1; yyval.set = xmalloc (sizeof (Confset)); yyval.set[0].cf = cf_dumpspec; yyval.set[0].v.sval = xstrdup (laststr); ; break;} -case 114: -#line 1181 "parser.y" +case 135: +#line 1299 "parser.y" { - psmsg ("throughputlog statement:", laststr); + pmsg ("throughputlog statement [%s]\n", laststr); yyval.n = 1; yyval.set = xmalloc (sizeof (Confset)); yyval.set[0].cf = cf_thruspec; yyval.set[0].v.sval = xstrdup (laststr); ; break;} -case 115: -#line 1192 "parser.y" +case 136: +#line 1311 "parser.y" +{ + pmsg ("httptiminglog statement [%s]\n", laststr); + yyval.n = 1; + yyval.set = xmalloc (sizeof (Confset)); + yyval.set[0].cf = cf_httptimingspec; + yyval.set[0].v.sval = xstrdup (laststr); + ; + break;} +case 137: +#line 1322 "parser.y" { setlaststr (laststring); free (laststring); laststring = 0; ; break;} -case 116: -#line 1201 "parser.y" +case 138: +#line 1331 "parser.y" { setlaststr (laststring); free (laststring); laststring = 0; ; break;} -case 117: -#line 1211 "parser.y" +case 139: +#line 1341 "parser.y" { - psmsg ("insertcookie statement:", laststr); + pmsg ("insertcookie statement [%s]\n", laststr); yyval.n = 1; yyval.set = xmalloc (sizeof (Confset)); yyval.set[0].cf = cf_stickycookiespec; yyval.set[0].v.sval = xstrdup (laststr); ; break;} -case 118: -#line 1222 "parser.y" +case 140: +#line 1352 "parser.y" { setlaststr (laststring); free (laststring); laststring = 0; ; break;} -case 119: -#line 1232 "parser.y" +case 141: +#line 1362 "parser.y" { - psmsg ("addclientheader statement:", laststr); + pmsg ("addclientheader statement [%s]\n", laststr); yyval.n = 1; yyval.set = xmalloc (sizeof(Confset)); yyval.set[0].cf = cf_addclientheaderspec; yyval.set[0].v.sval = xstrdup (laststr); ; break;} -case 120: -#line 1244 "parser.y" +case 142: +#line 1374 "parser.y" { - psmsg ("setclientheader statement:", laststr); + pmsg ("setclientheader statement [%s]\n", laststr); yyval.n = 1; yyval.set = xmalloc (sizeof(Confset)); yyval.set[0].cf = cf_setclientheaderspec; yyval.set[0].v.sval = xstrdup (laststr); ; break;} -case 121: -#line 1256 "parser.y" +case 143: +#line 1386 "parser.y" { - psmsg ("appendclientheader statement:", laststr); + pmsg ("appendclientheader statement [%s]\n", laststr); yyval.n = 1; yyval.set = xmalloc (sizeof(Confset)); yyval.set[0].cf = cf_appendclientheaderspec; yyval.set[0].v.sval = xstrdup (laststr); ; break;} -case 122: -#line 1268 "parser.y" +case 144: +#line 1398 "parser.y" { - psmsg ("addserverheader statement:", laststr); + pmsg ("addserverheader statement [%s]\n", laststr); yyval.n = 1; yyval.set = xmalloc (sizeof(Confset)); yyval.set[0].cf = cf_addserverheaderspec; yyval.set[0].v.sval = xstrdup (laststr); ; break;} -case 123: -#line 1280 "parser.y" +case 145: +#line 1410 "parser.y" { - psmsg ("setserverheader statement:", laststr); + pmsg ("setserverheader statement [%s]\n", laststr); yyval.n = 1; yyval.set = xmalloc (sizeof(Confset)); yyval.set[0].cf = cf_setserverheaderspec; yyval.set[0].v.sval = xstrdup (laststr); ; break;} -case 124: -#line 1292 "parser.y" +case 146: +#line 1422 "parser.y" { - psmsg ("appendserverheader statement:", laststr); + pmsg ("appendserverheader statement [%s]\n", laststr); yyval.n = 1; yyval.set = xmalloc (sizeof(Confset)); yyval.set[0].cf = cf_appendserverheaderspec; yyval.set[0].v.sval = xstrdup (laststr); ; break;} -case 125: -#line 1303 "parser.y" +case 147: +#line 1433 "parser.y" { setlaststr (laststring); free (laststring); laststring = 0; ; break;} -case 126: -#line 1310 "parser.y" +case 148: +#line 1440 "parser.y" { yyerrmsg = "HTTP header specifier expected"; ; break;} -case 127: -#line 1315 "parser.y" +case 149: +#line 1445 "parser.y" { yyerrmsg = "cookie specifier expected"; ; break;} -case 128: -#line 1320 "parser.y" +case 150: +#line 1450 "parser.y" { yyerrmsg = "number expected"; ; break;} -case 129: -#line 1325 "parser.y" +case 151: +#line 1455 "parser.y" { yyerrmsg = "hostname or IP address expected"; ; break;} -case 130: -#line 1330 "parser.y" +case 152: +#line 1460 "parser.y" { yyerrmsg = "'service' expected"; ; break;} -case 131: -#line 1335 "parser.y" +case 153: +#line 1465 "parser.y" { yyerrmsg = "backend definition statement expected"; ; break;} -case 132: -#line 1340 "parser.y" +case 154: +#line 1470 "parser.y" { yyerrmsg = "service body statement expected"; ; break;} -case 133: -#line 1345 "parser.y" +case 155: +#line 1475 "parser.y" { yyerrmsg = "semicolon (;) expected"; ; break;} -case 134: -#line 1350 "parser.y" +case 156: +#line 1480 "parser.y" { yyerrmsg = "'on' or 'off' expetcted"; ; break;} -case 135: -#line 1355 "parser.y" +case 157: +#line 1485 "parser.y" { yyerrmsg = "dispatch method expected"; ; break;} -case 136: -#line 1360 "parser.y" +case 158: +#line 1490 "parser.y" { yyerrmsg = "command line expected"; ; break;} -case 137: -#line 1365 "parser.y" +case 159: +#line 1495 "parser.y" { yyerrmsg = "file name expected"; ; break;} -case 138: -#line 1370 "parser.y" +case 160: +#line 1500 "parser.y" { yyerrmsg = "service name (identifier) expected"; ; break;} -case 139: -#line 1375 "parser.y" +case 161: +#line 1505 "parser.y" { yyerrmsg = "backend name (identifier) expected"; ; break;} -case 140: -#line 1380 "parser.y" +case 162: +#line 1510 "parser.y" { yyerrmsg = "IP address such as 1.2.3.4 or 'any' expected"; ; break;} -case 141: -#line 1385 "parser.y" +case 163: +#line 1515 "parser.y" { yyerrmsg = "Service type expected ('any', 'stickyhttp', ...)"; ; break;} -case 142: -#line 1390 "parser.y" +case 164: +#line 1520 "parser.y" { yyerrmsg = "Header inspection mode mode expected ('shallow' or 'deep')"; ; break;} -case 143: -#line 1395 "parser.y" +case 165: +#line 1525 "parser.y" { yyerrmsg = "IP filter(s) expected"; ; break;} -case 144: -#line 1400 "parser.y" +case 166: +#line 1530 "parser.y" { yyerrmsg = "username expected"; ; break;} -case 145: -#line 1405 "parser.y" +case 167: +#line 1535 "parser.y" { yyerrmsg = "state definition expected"; ; break;} +case 170: +#line 1550 "parser.y" +{ + yyerrmsg = "'{' expected"; +; + break;} +case 171: +#line 1554 "parser.y" +{ + yyerrmsg = "'}' expected"; +; + break;} +case 172: +#line 1558 "parser.y" +{ + yyerrmsg = "option statement (logactivity, tcpbuffersize, ...) expected"; +; + break;} } /* the action file gets copied in in place of this dollarsign */ #line 543 "/usr/share/bison.simple" @@ -2518,4 +2666,4 @@ yyerrhandle: } return 1; } -#line 1409 "parser.y" +#line 1561 "parser.y" diff --git a/src/lib/parser.h b/src/lib/parser.h @@ -37,27 +37,36 @@ #define BACKLOG 290 #define THROUGHPUTLOG 291 #define TRAFFICLOG 292 -#define STICKYCOOKIE 293 -#define ADDCLIENTHEADER 294 -#define SETCLIENTHEADER 295 -#define APPENDCLIENTHEADER 296 -#define ADDSERVERHEADER 297 -#define SETSERVERHEADER 298 -#define APPENDSERVERHEADER 299 -#define ALLOWFROM 300 -#define DENYFROM 301 -#define ALLOWFILE 302 -#define DENYFILE 303 -#define EXTERNALHANDLER 304 -#define USERACCOUNT 305 -#define ONEND 306 -#define HEADERINSPECTION 307 -#define DEEP 308 -#define SHALLOW 309 -#define STATE 310 -#define AVAILABLE 311 -#define UNAVAILABLE 312 -#define DOWN 313 +#define HTTPTIMINGLOG 293 +#define STICKYCOOKIE 294 +#define ADDCLIENTHEADER 295 +#define SETCLIENTHEADER 296 +#define APPENDCLIENTHEADER 297 +#define ADDSERVERHEADER 298 +#define SETSERVERHEADER 299 +#define APPENDSERVERHEADER 300 +#define ALLOWFROM 301 +#define DENYFROM 302 +#define ALLOWFILE 303 +#define DENYFILE 304 +#define EXTERNALHANDLER 305 +#define USERACCOUNT 306 +#define ONEND 307 +#define HEADERINSPECTION 308 +#define DEEP 309 +#define SHALLOW 310 +#define STATE 311 +#define AVAILABLE 312 +#define UNAVAILABLE 313 +#define DOWN 314 +#define OPTIONS 315 +#define LOGACTIVITY 316 +#define TCPBUFFERSIZE 317 +#define DNSCACHETTL 318 +#define LOGFACILITY 319 +#define SHMPERMISSIONS 320 +#define SLOPPYPORTBIND 321 +#define LEAVEPROCESSTITLE 322 extern YYSTYPE yylval; diff --git a/src/lib/parser.y b/src/lib/parser.y @@ -1,3 +1,4 @@ + /* Parser of crossroads configuration files */ %{ @@ -12,22 +13,15 @@ static Backend cur_backend; /* Storage for a handled backend */ static Service cur_service; /* Storage for a handled service */ /* Parser debugging related */ -/* #define PARSER_DEBUG */ -#ifdef PARSER_DEBUG - static void pmsg (char const *x) { - printf ("P: %s\n", x); - } - static void psmsg (char const *x, char const *y) { - printf ("P: %s %s\n", x, y); - } - static void pimsg(char const *x, int y) { - printf ("P: %s %d\n", x, y); +static void pmsg (char const *fmt, ...) { + va_list args; + + if (parser_debug) { + printf ("PARSER: "); + va_start (args, fmt); + vprintf (fmt, args); } -#else -# define pmsg(x) -# define psmsg(x,y) -# define pimsg(x,y) -#endif +} /* Conversion of yytext for symbol table */ #define SYMBOL (symtab_lookup((yytext))) @@ -60,13 +54,19 @@ static void setlaststr (char const *what) { /* Store an encountered number */ static int lastnr; static void setlastnr (char const *what) { - lastnr = atoi (what); + if (what && *what && *what == '0') + lastnr = strtol (what, 0, 8); + else + lastnr = atoi (what); } /* Store an encountered 'over' number */ static int lastovernr; static void setlastovernr (char const *what) { - lastovernr = atoi(what); + if (what && *what && *what == '0') + lastovernr = strtol (what, 0, 8); + else + lastovernr = atoi(what); } /* Store an encountered 'externalhandler' */ @@ -144,13 +144,15 @@ static void setuseraccount (char *username) { OVER DECAY REVIVINGINTERVAL CHECKINTERVAL RETRIES SHMKEY WEIGHT ONSTART ONFAIL BACKLOG - THROUGHPUTLOG TRAFFICLOG + THROUGHPUTLOG TRAFFICLOG HTTPTIMINGLOG STICKYCOOKIE ADDCLIENTHEADER SETCLIENTHEADER APPENDCLIENTHEADER ADDSERVERHEADER SETSERVERHEADER APPENDSERVERHEADER ALLOWFROM DENYFROM ALLOWFILE DENYFILE EXTERNALHANDLER USERACCOUNT ONEND HEADERINSPECTION DEEP SHALLOW STATE AVAILABLE UNAVAILABLE DOWN + OPTIONS LOGACTIVITY TCPBUFFERSIZE DNSCACHETTL LOGFACILITY + SHMPERMISSIONS SLOPPYPORTBIND LEAVEPROCESSTITLE %% /* Config file grammar rules */ @@ -163,11 +165,111 @@ input: ; element: + service_element +| + option_element +; + +option_element: + OPTIONS + openbrace + option_statements + closebrace +; + +option_statements: + option_statements + option_statement +| + option_statement +; + +option_statement: + option_statement_expected + optstat +; + +optstat: + logactivity_statement +| + tcpbuffersize_statement +| + dnscachettl_statement +| + logfacility_statement +| + shmpermissions_statement +| + sloppyportbind_statement +| + leaveprocesstitle_statement +; + +logactivity_statement: + LOGACTIVITY + onoff_expected + onoff + semicol { + opt.log_activity = lastnr; + } +; + +tcpbuffersize_statement: + TCPBUFFERSIZE + number + semicol { + opt.tcp_bufsz = lastnr; + } +; + +dnscachettl_statement: + DNSCACHETTL + number + semicol { + opt.dns_cachettl = lastnr; + } +; + +logfacility_statement: + LOGFACILITY + number + semicol { + opt.log_facility = lastnr; + } +; + +shmpermissions_statement: + SHMPERMISSIONS + number + semicol { + opt.shmperm = lastnr; + } +; + +sloppyportbind_statement: + SLOPPYPORTBIND + onoff_expected + onoff + semicol { + opt.sloppyportbind = lastnr; + } +; + +leaveprocesstitle_statement: + LEAVEPROCESSTITLE + onoff_expected + onoff + semicol { + opt.leave_proctitle = lastnr; + } +; + +service_element: service servicename - '{' + openbrace servicestatements - '}' { + closebrace { /* Check integrity, supply defaults */ check_service (cur_service); @@ -194,7 +296,7 @@ service: servicename: servicename_expected IDENTIFIER { - psmsg ("service:", SYMBOL); + pmsg ("service [%s]\n", SYMBOL); for (i = 0; i < nservice; i++) if (!strcmp (service[i].name, SYMBOL)) error ("Duplicate definition of service '%s'", SYMBOL); @@ -216,159 +318,166 @@ servicestatement: servicebody: portstatement { - pimsg ("sevice port:", $1.set[0].v.ival); + pmsg ("sevice port [%d]\n", $1.set[0].v.ival); cur_service.port = $1.set[0].v.ival; free ($1.set); } | bindstatement { - psmsg ("service binding:", $1.set[0].v.sval); + pmsg ("service binding [%s]\n", $1.set[0].v.sval); cur_service.bind = $1.set[0].v.sval; free ($1.set); } | verbositystatement { - pimsg ("service verbosity:", $1.set[0].v.ival); + pmsg ("service verbosity [%d]\n", $1.set[0].v.ival); cur_service.verbosity = $1.set[0].v.ival; free ($1.set); } | dispatchmodestatement { - pimsg ("service dispatch mode:", $1.set[0].v.ival); - pimsg ("service dispatch over:", lastovernr); - psmsg ("service dispatch exth:", lastext); + pmsg ("service dispatch mode [%d]\n", $1.set[0].v.ival); + pmsg ("service dispatch over [%d]\n", lastovernr); + pmsg ("service dispatch exthandler [%s]\n", lastext); cur_service.dispatchtype = $1.set[0].v.ival; cur_service.dispatchover = lastovernr; - cur_service.dispatchext = lastext; + cur_service.dispatchext = xstrdup(lastext); free ($1.set); } | revivingintervalstatement { - pimsg ("service revival interval:", $1.set[0].v.ival); - psmsg ("service revival cmd:", $1.set[1].v.sval); + pmsg ("service revival interval [%d]\n", $1.set[0].v.ival); + pmsg ("service revival cmd [%s]\n", $1.set[1].v.sval); cur_service.rev_interval = $1.set[0].v.ival; cur_service.check_cmd = $1.set[1].v.sval; free ($1.set); } | checkintervalstatement { - pimsg ("service check interval:", $1.set[0].v.ival); - psmsg ("service check cmd:", $1.set[1].v.sval); + pmsg ("service check interval [%d]\n", $1.set[0].v.ival); + pmsg ("service check cmd [%s]\n", $1.set[1].v.sval); cur_service.check_interval = $1.set[0].v.ival; cur_service.check_cmd = $1.set[1].v.sval; } | backlogstatement { - pimsg ("service backlog:", $1.set[0].v.ival); + pmsg ("service backlog [%d]\n", $1.set[0].v.ival); cur_service.backlog = $1.set[0].v.ival; free ($1.set); } | shmkeystatement { - pimsg ("service shmkey:", $1.set[0].v.ival); + pmsg ("service shmkey [%d]\n", $1.set[0].v.ival); cur_service.shmkey = $1.set[0].v.ival; free ($1.set); } | connectiontimeoutstatement { - pimsg ("connection timout:", $1.set[0].v.ival); + pmsg ("connection timout [%d]\n", $1.set[0].v.ival); cur_service.connectiontimeout = $1.set[0].v.ival; free ($1.set); } | maxconnectionsstatement { - pimsg ("max clients in service:", $1.set[0].v.ival); + pmsg ("max clients in service [%d]\n", $1.set[0].v.ival); cur_service.maxconnections = $1.set[0].v.ival; free ($1.set); } | typestatement { - pimsg ("service type: ", $1.set[0].v.ival); + pmsg ("service type [%d]\n", $1.set[0].v.ival); cur_service.type = $1.set[0].v.ival; free ($1.set); } | inspectionstatement { - pimsg ("service header inspection: ", $1.set[0].v.ival); + pmsg ("service header inspection [%d]\n", $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); + pmsg ("allow from [%s]\n", $1.set[0].v.sval); add_allowfrom ($1.set[0].v.sval); free ($1.set); } | allowfilestatement { - psmsg ("allow file: ", $1.set[0].v.sval); + pmsg ("allow file [%s]\n", $1.set[0].v.sval); cur_service.allowfile = $1.set[0].v.sval; free ($1.set); } | denyfromstatement { - psmsg ("deny from: ", $1.set[0].v.sval); + pmsg ("deny from [%s]\n", $1.set[0].v.sval); add_denyfrom ($1.set[0].v.sval); free ($1.set); } | denyfilestatement { - psmsg ("deny file: ", $1.set[0].v.sval); + pmsg ("deny file [%s]\n", $1.set[0].v.sval); cur_service.denyfile = $1.set[0].v.sval; free ($1.set); } | useraccountstatement { - psmsg ("user account: ", $1.set[0].v.sval); + pmsg ("user account [%s]\n", $1.set[0].v.sval); setuseraccount ($1.set[0].v.sval); free ($1.set[0].v.sval); free ($1.set); } | backendblock { - pimsg ("converting backend statements, count is", $1.n); + pmsg ("converting backend statements, count is [%d]\n", $1.n); for (i = 0; i < $1.n; i++) switch ($1.set[i].cf) { case cf_portspec: - pimsg ("backend block port:", $1.set[i].v.ival); + pmsg ("backend port [%d]\n", $1.set[i].v.ival); cur_backend.initial_port = $1.set[i].v.ival; break; case cf_serverspec: - psmsg ("backend block server:", $1.set[i].v.sval); + pmsg ("backend server [%s]\n", $1.set[i].v.sval); cur_backend.initial_server = serverpart ($1.set[i].v.sval); cur_backend.initial_port = portpart ($1.set[i].v.sval); free ($1.set[i].v.sval); break; case cf_verbosityspec: - pimsg ("backend block verbosity:", $1.set[i].v.ival); + pmsg ("backend verbosity [%d]\n", $1.set[i].v.ival); cur_backend.verbosity = $1.set[i].v.ival; break; case cf_onstartspec: - psmsg ("backend block onstart:", $1.set[i].v.sval); + pmsg ("backend onstart [%s]\n", $1.set[i].v.sval); cur_backend.onstart = $1.set[i].v.sval; break; case cf_onfailspec: - psmsg ("backend block onfail:", $1.set[i].v.sval); + pmsg ("backend onfail [%s]\n", $1.set[i].v.sval); cur_backend.onfail = $1.set[i].v.sval; break; case cf_onendspec: - psmsg ("backend block onend:", $1.set[i].v.sval); + pmsg ("backend onend [%s]\n", $1.set[i].v.sval); cur_backend.onend = $1.set[i].v.sval; break; case cf_dumpspec: - psmsg ("backend trafficlog:", $1.set[i].v.sval); + pmsg ("backend trafficlog [%s]\n", $1.set[i].v.sval); cur_backend.dumpfile = $1.set[i].v.sval; break; case cf_thruspec: - psmsg ("backend throughputlog:", $1.set[i].v.sval); + pmsg ("backend throughputlog [%s]\n", $1.set[i].v.sval); cur_backend.thruputfile = $1.set[i].v.sval; break; + case cf_httptimingspec: + if (cur_service.type != type_http) + error ("'httptiminglog' only allowed in 'type http' " + "service definitions"); + pmsg ("backend http timing log [%s]\n", $1.set[i].v.sval); + cur_backend.timinglog = $1.set[i].v.sval; + break; case cf_weightspec: - pimsg ("backend weight:", $1.set[i].v.ival); + pmsg ("backend weight [%d]\n", $1.set[i].v.ival); cur_backend.weight = $1.set[i].v.ival; break; case cf_decayspec: - pimsg ("backend decay:", $1.set[i].v.ival); + pmsg ("backend decay [%d]\n", $1.set[i].v.ival); if ($1.set[i].v.ival >= 100) error ("Decay specifier %d must be a percentage, " "never more than 99", @@ -376,17 +485,17 @@ servicebody: cur_backend.decay = $1.set[i].v.ival; break; case cf_maxconnectionsspec: - pimsg ("backend max clients: ", $1.set[i].v.ival); + pmsg ("backend max clients [%d]\n", $1.set[i].v.ival); cur_backend.maxconnections = $1.set[i].v.ival; break; case cf_stickycookiespec: - psmsg ("backend sticky cookie:", - $1.set[i].v.sval); + pmsg ("backend sticky cookie [%s]\n", + $1.set[i].v.sval); cur_backend.stickycookie = $1.set[i].v.sval; break; case cf_addclientheaderspec: - psmsg ("client header to add:", - $1.set[i].v.sval); + pmsg ("client header to add [%s]\n", + $1.set[i].v.sval); cur_backend.addclientheader = xrealloc (cur_backend.addclientheader, (cur_backend.naddclientheader + 1) * @@ -396,8 +505,8 @@ servicebody: $1.set[i].v.sval; break; case cf_setclientheaderspec: - psmsg ("client header to set:", - $1.set[i].v.sval); + pmsg ("client header to set [%s]\n", + $1.set[i].v.sval); cur_backend.setclientheader = xrealloc (cur_backend.setclientheader, (cur_backend.nsetclientheader + 1) * @@ -407,8 +516,8 @@ servicebody: $1.set[i].v.sval; break; case cf_appendclientheaderspec: - psmsg ("client header to append:", - $1.set[i].v.sval); + pmsg ("client header to append [%s]\n", + $1.set[i].v.sval); cur_backend.appendclientheader = xrealloc (cur_backend.appendclientheader, (cur_backend.nappendclientheader + 1) * @@ -418,8 +527,8 @@ servicebody: $1.set[i].v.sval; break; case cf_addserverheaderspec: - psmsg ("server header to add:", - $1.set[i].v.sval); + pmsg ("server header to add [%s]\n", + $1.set[i].v.sval); cur_backend.addserverheader = xrealloc (cur_backend.addserverheader, (cur_backend.naddserverheader + 1) * @@ -429,8 +538,8 @@ servicebody: $1.set[i].v.sval; break; case cf_setserverheaderspec: - psmsg ("server header to set:", - $1.set[i].v.sval); + pmsg ("server header to set [%s]\n", + $1.set[i].v.sval); cur_backend.setserverheader = xrealloc (cur_backend.setserverheader, (cur_backend.nsetserverheader + 1) * @@ -440,8 +549,8 @@ servicebody: $1.set[i].v.sval; break; case cf_appendserverheaderspec: - psmsg ("server header to append:", - $1.set[i].v.sval); + pmsg ("server header to append:", + $1.set[i].v.sval); cur_backend.appendserverheader = xrealloc (cur_backend.appendserverheader, (cur_backend.nappendserverheader + 1) * @@ -451,11 +560,11 @@ servicebody: $1.set[i].v.sval; break; case cf_retriesspec: - pimsg ("backend retries:", $1.set[i].v.ival); + pmsg ("backend retries [%d]\n", $1.set[i].v.ival); cur_backend.retries = $1.set[i].v.ival; break; case cf_statespec: - pimsg ("backend initial state:", $1.set[i].v.ival); + pmsg ("backend initial state [%d]\n", $1.set[i].v.ival); cur_backend.initial_avail = $1.set[i].v.ival; break; default: @@ -475,6 +584,7 @@ servicebody: cur_backend.weight = 1; if (cur_backend.retries < 1) cur_backend.retries = 1; + /* if (! cur_backend.onstart) cur_backend.onstart = xstrdup (""); if (! cur_backend.onfail) @@ -483,18 +593,21 @@ servicebody: cur_backend.onend = xstrdup (""); if (! cur_backend.thruputfile) cur_backend.thruputfile = xstrdup (""); + if (! cur_backend.timinglog) + cur_backend.timinglog = xstrdup (""); if (! cur_backend.dumpfile) cur_backend.dumpfile = xstrdup (""); if (! cur_backend.stickycookie) cur_backend.stickycookie = xstrdup (""); - + */ + /* Add to the list. */ cur_service.backend = xrealloc (cur_service.backend, ++cur_service.nbackend * sizeof(Backend)); cur_service.backend[cur_service.nbackend - 1] = cur_backend; - pimsg ("this was backend definition", cur_service.nbackend); + pmsg ("this was backend definition [%d]\n", cur_service.nbackend); memset (&cur_backend, 0, sizeof(cur_backend)); } ; @@ -503,7 +616,7 @@ portstatement: PORT number semicol { - pimsg ("port statement:", lastnr); + pmsg ("port statement [%d]\n", lastnr); $$.n = 1; $$.set = xmalloc (sizeof(Confset)); $$.set[0].cf = cf_portspec; @@ -515,7 +628,7 @@ bindstatement: BINDTO ipaddress semicol { - psmsg ("bindto statement:", laststr); + pmsg ("bindto statement [%d]\n", laststr); $$.n = 1; $$.set = xmalloc (sizeof(Confset)); $$.set[0].cf = cf_bindspec; @@ -549,7 +662,7 @@ verbositystatement: onoff_expected onoff semicol { - pimsg ("verbosity statement:", lastnr); + pmsg ("verbosity statement [%d]\n", lastnr); $$.n = 1; $$.set = xmalloc (sizeof(Confset)); $$.set[0].cf = cf_verbosityspec; @@ -589,7 +702,7 @@ dispatchtail: dispatchover: OVER overnumber { - pimsg ("dispatch mode statement:", lastnr); + pmsg ("dispatch mode statement [%d]\n", lastnr); $$.n = 1; $$.set = xmalloc (sizeof(Confset)); $$.set[0].cf = cf_dispatchspec; @@ -612,7 +725,7 @@ overnumber: dispatchext: commandline { - psmsg ("external handler:", laststr); + pmsg ("external handler [%s]\n", laststr); if (lastnr != ds_externalhandler) error ("Service %s: this dispatch mode doesn't support " "an external handler", cur_service.name); @@ -667,7 +780,7 @@ useraccountstatement: USERACCOUNT useraccount semicol { - psmsg ("user account statement:", laststr); + pmsg ("user account statement [%d]\n", laststr); $$.n = 1; $$.set = xmalloc (sizeof(Confset)); $$.set[0].cf = cf_useraccountspec; @@ -689,13 +802,13 @@ revivingintervalstatement: number opt_externalhandler semicol { - pimsg ("reviving interval statement:", lastnr); + pmsg ("reviving interval statement [%d]\n", lastnr); $$.n = 2; $$.set = xmalloc (2 * sizeof(Confset)); $$.set[0].cf = cf_revivespec; $$.set[0].v.ival = lastnr; if ($3.n) { - psmsg ("reviving externalhandler:", $3.set[0].v.sval); + pmsg ("reviving externalhandler [%s]\n", $3.set[0].v.sval); $$.set[1].v.sval = $3.set[0].v.sval; } else $$.set[1].v.sval = 0; @@ -707,13 +820,13 @@ checkintervalstatement: number opt_externalhandler semicol { - pimsg ("check interval:", lastnr); + pmsg ("check interval [%d]\n", lastnr); $$.n = 2; $$.set = xmalloc (2 * sizeof(Confset)); $$.set[0].cf = cf_checkspec; $$.set[0].v.ival = lastnr; if ($3.n) { - psmsg ("check externalhandler:", $3.set[0].v.sval); + pmsg ("check externalhandler [%s]\n", $3.set[0].v.sval); $$.set[1].v.sval = $3.set[0].v.sval; } else $$.set[1].v.sval = 0; @@ -741,7 +854,7 @@ backlogstatement: BACKLOG number semicol { - pimsg ("backlog statement:", lastnr); + pmsg ("backlog statement [%d]\n", lastnr); $$.n = 1; $$.set = xmalloc (sizeof(Confset)); $$.set[0].cf = cf_backlogspec; @@ -753,7 +866,7 @@ shmkeystatement: SHMKEY number semicol { - pimsg ("shmkey statement:", lastnr); + pmsg ("shmkey statement [%d]\n", lastnr); $$.n = 1; $$.set = xmalloc (sizeof(Confset)); $$.set[0].cf = cf_shmkeyspec; @@ -765,7 +878,7 @@ connectiontimeoutstatement: CONNECTIONTIMEOUT number semicol { - pimsg ("connection timeout statement:", lastnr); + pmsg ("connection timeout statement [%d]\n", lastnr); $$.n = 1; $$.set = xmalloc (sizeof(Confset)); $$.set[0].cf = cf_connectiontimeoutspec; @@ -777,7 +890,7 @@ maxconnectionsstatement: MAXCONNECTIONS number semicol { - pimsg ("max clients statement (service):", lastnr); + pmsg ("max clients statement (service) [%d]\n", lastnr); $$.n = 1; $$.set = xmalloc (sizeof(Confset)); $$.set[0].cf = cf_maxconnectionsspec; @@ -789,7 +902,7 @@ typestatement: TYPE typespec semicol { - pimsg ("service type:", lastnr); + pmsg ("service type [%d]\n", lastnr); $$.n = 1; $$.set = xmalloc (sizeof(Confset)); $$.set[0].cf = cf_typespec; @@ -816,7 +929,7 @@ inspectionstatement: HEADERINSPECTION shallowdeepspec semicol { - pimsg ("service header inspection: ", lastnr); + pmsg ("service header inspection [%d]\n", lastnr); $$.n = 1; $$.set = xmalloc (sizeof(Confset)); $$.set[0].cf = cf_inspectionspec; @@ -843,7 +956,7 @@ allowfromstatement: ALLOWFROM ipfilters semicol { - psmsg ("allow from: ", laststr); + pmsg ("allow from [%s]\n", laststr); $$.n = 1; $$.set = xmalloc (sizeof(Confset)); $$.set[0].cf = cf_allowfromspec; @@ -855,7 +968,7 @@ denyfromstatement: DENYFROM ipfilters semicol { - psmsg ("allow from: ", laststr); + pmsg ("deny from [%s]\n", laststr); $$.n = 1; $$.set = xmalloc (sizeof(Confset)); $$.set[0].cf = cf_denyfromspec; @@ -867,7 +980,7 @@ allowfilestatement: ALLOWFILE filename semicol { - psmsg ("allow file: ", laststr); + pmsg ("allow file [%s]\n", laststr); $$.n = 1; $$.set = xmalloc (sizeof(Confset)); $$.set[0].cf = cf_allowfilespec; @@ -879,7 +992,7 @@ denyfilestatement: DENYFILE filename semicol { - psmsg ("allow file: ", laststr); + pmsg ("deny file [%s]\n", laststr); $$.n = 1; $$.set = xmalloc (sizeof(Confset)); $$.set[0].cf = cf_allowfilespec; @@ -899,9 +1012,9 @@ ipfilters: backendblock: BACKEND backendname - '{' + openbrace backenddefinitions - '}' { + closebrace { $$ = $4; } ; @@ -909,7 +1022,7 @@ backendblock: backendname: backendname_expected IDENTIFIER { - psmsg ("backend name:", SYMBOL); + pmsg ("backend name [%s]\n", SYMBOL); for (i = 0; i < cur_service.nbackend; i++) if (!strcmp (cur_service.backend[i].name, SYMBOL)) error ("Service %s: back end '%s' multiply defined", @@ -941,102 +1054,107 @@ backenddefinition: backendstatement: serverstatement { - psmsg ("backend server:", $1.set[0].v.sval); + pmsg ("backend server [%s]\n", $1.set[0].v.sval); $$ = $1; } | portstatement { - pimsg ("backend port:", $1.set[0].v.ival); + pmsg ("backend port [%d]\n", $1.set[0].v.ival); $$ = $1; } | verbositystatement { - pimsg ("backend verbosity:", $1.set[0].v.ival); + pmsg ("backend verbosity [%d]\n", $1.set[0].v.ival); $$ = $1; } | onstartstatement { - psmsg ("backend onstart:", $1.set[0].v.sval); + pmsg ("backend onstart [%s]\n", $1.set[0].v.sval); $$ = $1; } | onendstatement { - psmsg ("backend onend:", $1.set[0].v.sval); + pmsg ("backend onend [%s]\n", $1.set[0].v.sval); $$ = $1; } | onfailstatement { - psmsg ("backend onfail:", $1.set[0].v.sval); + pmsg ("backend onfail [%s]\n", $1.set[0].v.sval); $$ = $1; } | dumptrafficstatement { - psmsg ("backend trafficlog:", $1.set[0].v.sval); + pmsg ("backend trafficlog [%s]\n", $1.set[0].v.sval); $$ = $1; } | throughputstatement { - psmsg ("backend trafficlog:", $1.set[0].v.sval); + pmsg ("backend trafficlog [%s]\n", $1.set[0].v.sval); + $$ = $1; + } +| + httptiminglogstatement { + pmsg ("backend HTTP timing log [%s]\n", $1.set[0].v.sval); $$ = $1; } | weightstatement { - pimsg ("backend weight:", $1.set[0].v.ival); + pmsg ("backend weight [%d]\n", $1.set[0].v.ival); $$ = $1; } | decaystatement { - pimsg ("backend decay:", $1.set[0].v.ival); + pmsg ("backend decay [%d]\n", $1.set[0].v.ival); $$ = $1; } | maxconnectionsstatement { - pimsg ("backend maxconnections:", $1.set[0].v.ival); + pmsg ("backend maxconnections [%d]\n", $1.set[0].v.ival); $$ = $1; } | stickycookiestatement { - psmsg ("backend sticky cookie:", $1.set[0].v.sval); + pmsg ("backend sticky cookie [%s]\n", $1.set[0].v.sval); $$ = $1; } | addclientheaderstatement { - psmsg ("addclientheader:", $1.set[0].v.sval); + pmsg ("addclientheader [%s]\n", $1.set[0].v.sval); $$ = $1; } | setclientheaderstatement { - psmsg ("setclientheader:", $1.set[0].v.sval); + pmsg ("setclientheader [%s]\n", $1.set[0].v.sval); $$ = $1; } | appendclientheaderstatement { - psmsg ("appendclientheader:", $1.set[0].v.sval); + pmsg ("appendclientheader [%s]\n", $1.set[0].v.sval); $$ = $1; } | addserverheaderstatement { - psmsg ("addserverheader:", $1.set[0].v.sval); + pmsg ("addserverheader [%s]\n", $1.set[0].v.sval); $$ = $1; } | setserverheaderstatement { - psmsg ("setserverheader:", $1.set[0].v.sval); + pmsg ("setserverheader [%s]\n", $1.set[0].v.sval); $$ = $1; } | appendserverheaderstatement { - psmsg ("appendserverheader:", $1.set[0].v.sval); + pmsg ("appendserverheader [%s]\n", $1.set[0].v.sval); $$ = $1; } | retriesstatement { - pimsg ("backend retries:", $1.set[0].v.ival); + pmsg ("backend retries [%d]\n", $1.set[0].v.ival); $$ = $1; } | initialstatestatement { - pimsg ("backend state:", $1.set[0].v.ival); + pmsg ("backend state [%d]\n", $1.set[0].v.ival); $$ = $1; } ; @@ -1046,7 +1164,7 @@ serverstatement: serveraddress_expected serveraddress semicol { - psmsg ("server statement:", laststr); + pmsg ("server statement [%s]\n", laststr); $$.n = 1; $$.set = xmalloc (sizeof (Confset)); $$.set[0].cf = cf_serverspec; @@ -1058,7 +1176,7 @@ weightstatement: WEIGHT number semicol { - pimsg ("weight statement", lastnr); + pmsg ("weight statement [%d]\n", lastnr); $$.n = 1; $$.set = xmalloc (sizeof (Confset)); $$.set[0].cf = cf_weightspec; @@ -1070,7 +1188,7 @@ decaystatement: DECAY number semicol { - pimsg ("decay statement", lastnr); + pmsg ("decay statement [%d]\n", lastnr); $$.n = 1; $$.set = xmalloc (sizeof (Confset)); $$.set[0].cf = cf_decayspec; @@ -1088,7 +1206,7 @@ retriesstatement: RETRIES number semicol { - pimsg ("retries:", lastnr); + pmsg ("retries [%d]\n", lastnr); $$.n = 1; $$.set = xmalloc (sizeof(Confset)); $$.set[0].cf = cf_retriesspec; @@ -1100,7 +1218,7 @@ initialstatestatement: STATE statedef semicol { - pimsg ("state:", lastnr); + pmsg ("state [%d]\n", lastnr); $$.n = 1; $$.set = xmalloc (sizeof(Confset)); $$.set[0].cf = cf_statespec; @@ -1131,7 +1249,7 @@ onstartstatement: ONSTART commandline semicol { - psmsg ("onstart statement:", laststr); + pmsg ("onstart statement [%s]\n", laststr); $$.n = 1; $$.set = xmalloc (sizeof (Confset)); $$.set[0].cf = cf_onstartspec; @@ -1143,7 +1261,7 @@ onfailstatement: ONFAIL commandline semicol { - psmsg ("onfail statement:", laststr); + pmsg ("onfail statement [%s]\n", laststr); $$.n = 1; $$.set = xmalloc (sizeof (Confset)); $$.set[0].cf = cf_onfailspec; @@ -1155,7 +1273,7 @@ onendstatement: ONEND commandline semicol { - psmsg ("onend statement:", laststr); + pmsg ("onend statement [%s]\n", laststr); $$.n = 1; $$.set = xmalloc (sizeof (Confset)); $$.set[0].cf = cf_onendspec; @@ -1167,7 +1285,7 @@ dumptrafficstatement: TRAFFICLOG filename semicol { - psmsg ("trafficlog statement:", laststr); + pmsg ("trafficlog statement [%s]\n", laststr); $$.n = 1; $$.set = xmalloc (sizeof (Confset)); $$.set[0].cf = cf_dumpspec; @@ -1179,7 +1297,7 @@ throughputstatement: THROUGHPUTLOG filename semicol { - psmsg ("throughputlog statement:", laststr); + pmsg ("throughputlog statement [%s]\n", laststr); $$.n = 1; $$.set = xmalloc (sizeof (Confset)); $$.set[0].cf = cf_thruspec; @@ -1187,6 +1305,18 @@ throughputstatement: } ; +httptiminglogstatement: + HTTPTIMINGLOG + filename + semicol { + pmsg ("httptiminglog statement [%s]\n", laststr); + $$.n = 1; + $$.set = xmalloc (sizeof (Confset)); + $$.set[0].cf = cf_httptimingspec; + $$.set[0].v.sval = xstrdup (laststr); + } +; + commandline: commandline_expected STRING { @@ -1209,7 +1339,7 @@ stickycookiestatement: STICKYCOOKIE cookiespecifier semicol { - psmsg ("insertcookie statement:", laststr); + pmsg ("insertcookie statement [%s]\n", laststr); $$.n = 1; $$.set = xmalloc (sizeof (Confset)); $$.set[0].cf = cf_stickycookiespec; @@ -1230,7 +1360,7 @@ addclientheaderstatement: ADDCLIENTHEADER headerstring semicol { - psmsg ("addclientheader statement:", laststr); + pmsg ("addclientheader statement [%s]\n", laststr); $$.n = 1; $$.set = xmalloc (sizeof(Confset)); $$.set[0].cf = cf_addclientheaderspec; @@ -1242,7 +1372,7 @@ setclientheaderstatement: SETCLIENTHEADER headerstring semicol { - psmsg ("setclientheader statement:", laststr); + pmsg ("setclientheader statement [%s]\n", laststr); $$.n = 1; $$.set = xmalloc (sizeof(Confset)); $$.set[0].cf = cf_setclientheaderspec; @@ -1254,7 +1384,7 @@ appendclientheaderstatement: APPENDCLIENTHEADER headerstring semicol { - psmsg ("appendclientheader statement:", laststr); + pmsg ("appendclientheader statement [%s]\n", laststr); $$.n = 1; $$.set = xmalloc (sizeof(Confset)); $$.set[0].cf = cf_appendclientheaderspec; @@ -1266,7 +1396,7 @@ addserverheaderstatement: ADDSERVERHEADER headerstring semicol { - psmsg ("addserverheader statement:", laststr); + pmsg ("addserverheader statement [%s]\n", laststr); $$.n = 1; $$.set = xmalloc (sizeof(Confset)); $$.set[0].cf = cf_addserverheaderspec; @@ -1278,7 +1408,7 @@ setserverheaderstatement: SETSERVERHEADER headerstring semicol { - psmsg ("setserverheader statement:", laststr); + pmsg ("setserverheader statement [%s]\n", laststr); $$.n = 1; $$.set = xmalloc (sizeof(Confset)); $$.set[0].cf = cf_setserverheaderspec; @@ -1290,7 +1420,7 @@ appendserverheaderstatement: APPENDSERVERHEADER headerstring semicol { - psmsg ("appendserverheader statement:", laststr); + pmsg ("appendserverheader statement [%s]\n", laststr); $$.n = 1; $$.set = xmalloc (sizeof(Confset)); $$.set[0].cf = cf_appendserverheaderspec; @@ -1406,3 +1536,25 @@ statedef_expected: { yyerrmsg = "state definition expected"; } ; + +openbrace: + openbrace_expected + '{' +; + +closebrace: + closebrace_expected + '}' +; + +openbrace_expected: { + yyerrmsg = "'{' expected"; +} + +closebrace_expected: { + yyerrmsg = "'}' expected"; +} + +option_statement_expected: { + yyerrmsg = "option statement (logactivity, tcpbuffersize, ...) expected"; +} diff --git a/src/lib/parserclose.c b/src/lib/parserclose.c @@ -1,5 +1,5 @@ /************************************************************************* - * This file is part of Crosroads 1.71, a load balancer and fail over + * This file is part of Crosroads 1.75, 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.71, a load balancer and fail over + * This file is part of Crosroads 1.75, 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.71, a load balancer and fail over + * This file is part of Crosroads 1.75, 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.71, a load balancer and fail over + * This file is part of Crosroads 1.75, a load balancer and fail over * utility for TCP. Copyright (c) Karel Kubat, distributed under GPL. * Visit http://crossroads.e-tunity.com for information. *************************************************************************/ diff --git a/src/lib/parserrun.c b/src/lib/parserrun.c @@ -1,5 +1,5 @@ /************************************************************************* - * This file is part of Crosroads 1.71, a load balancer and fail over + * This file is part of Crosroads 1.75, 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.71, a load balancer and fail over + * This file is part of Crosroads 1.75, 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.71, a load balancer and fail over + * This file is part of Crosroads 1.75, 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.71, a load balancer and fail over + * This file is part of Crosroads 1.75, a load balancer and fail over * utility for TCP. Copyright (c) Karel Kubat, distributed under GPL. * Visit http://crossroads.e-tunity.com for information. *************************************************************************/ @@ -10,9 +10,6 @@ void runservice () { int pid; int first_serving = 1; - msg ("Service %s (on port %d): STARTING", - activeservice->name, activeservice->port); - /* Allocate the shared mem segment. */ alloc_reporter(activeservice, 1); @@ -36,14 +33,26 @@ void runservice () { return; } - /* Child branch */ - if (!leave_proctitle) - setproctitle ("crossroads - Service %s: listening", - activeservice->name); + /*** Child branch ***/ + + /* We've forked for the first time */ + daemonized++; + program_stage = stage_waiting; + + /* Promote verbosity. */ + flag_verbose = activeservice->verbosity; + + /* Provide configuration feedback */ + config_msg(); + + msg ("Service %s (on port %d): STARTING", + activeservice->name, activeservice->port); + + set_program_title ("crossroads - Service %s: listening", + activeservice->name); close (0); close (1); close (2); - daemonized++; if ( (open ("/dev/null", O_RDONLY) < 0) || (open ("/dev/null", O_WRONLY) < 0) || (open ("/dev/null", O_WRONLY) < 0) ) @@ -51,15 +60,9 @@ void runservice () { "failed to reopen stdin/out/err on /dev/null", activeservice->name); if (setsid() < 0) - error ("Service %s: failed to become seesion leader", + error ("Service %s: failed to become session leader", activeservice->name); - /* Promote verbosity. */ - flag_verbose = activeservice->verbosity; - - /* We've forked for the first time */ - program_stage = stage_waiting; - /* In 'forever' mode, we create a server-side socket and ask tcpserve() * to service it. tcpserve() will return to us if there are no back * ends to service the request. In that case, we close the listening @@ -78,7 +81,7 @@ void runservice () { * Create the socket, bind to port. */ if ( (listen_sock = make_socket (activeservice->port, activeservice->bind)) < 0 ) { - if (!sloppyportbind) + if (!opt.sloppyportbind) error ("Service %s: failed to listen to port %d: %s", activeservice->name, activeservice->port, strerror(errno)); diff --git a/src/lib/setproctitle.c b/src/lib/setproctitle.c @@ -1,5 +1,5 @@ /************************************************************************* - * This file is part of Crosroads 1.71, a load balancer and fail over + * This file is part of Crosroads 1.75, 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/setprogramtitle.c b/src/lib/setprogramtitle.c @@ -0,0 +1,20 @@ +/************************************************************************* + * This file is part of Crosroads 1.75, 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, ...) { + char *buf; + va_list args; + + if (opt.leave_proctitle) + return; + va_start (args, fmt); + buf = str_vprintf (fmt, args); + va_end (args); + setproctitle (buf); + free (buf); +} diff --git a/src/lib/showconfig.c b/src/lib/showconfig.c @@ -1,5 +1,5 @@ /************************************************************************* - * This file is part of Crosroads 1.71, a load balancer and fail over + * This file is part of Crosroads 1.75, a load balancer and fail over * utility for TCP. Copyright (c) Karel Kubat, distributed under GPL. * Visit http://crossroads.e-tunity.com for information. *************************************************************************/ @@ -7,7 +7,7 @@ #include "../crossroads.h" #define SHOWDEF(a,b,c) \ - printf ("%-22s %-31s %s \n", b, c, a ? "yes" : "no"); + printf ("%-22s %-31s: %s \n", b, c, a ? "yes" : "no"); void show_config () { printf ("VER version: %s\n" @@ -40,15 +40,16 @@ void show_config () { 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_STRUPR, "HAVE_STRUPR", "strupr() present:"); - SHOWDEF (HAVE_STRCASESTR, "HAVE_STRCASESTR", "strcasestr() present:"); - SHOWDEF (HAVE_SETPROCTITLE, "HAVE_SETPROCTITLE", "setproctitle() 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_STRUPR, "HAVE_STRUPR", "strupr() present"); + SHOWDEF (HAVE_STRCASESTR, "HAVE_STRCASESTR", "strcasestr() present"); + SHOWDEF (HAVE_SETPROCTITLE, "HAVE_SETPROCTITLE", "setproctitle() present"); + SHOWDEF (HAVE_STRNSTR, "HAVE_STRNSTR", "strnstr() present"); SHOWDEF (HAVE_PROGNAME_FULL,"HAVE_PROGNAME_FULL","__progname_full present"); } diff --git a/src/lib/stagetostring.c b/src/lib/stagetostring.c @@ -1,5 +1,5 @@ /************************************************************************* - * This file is part of Crosroads 1.71, a load balancer and fail over + * This file is part of Crosroads 1.75, 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.71, a load balancer and fail over + * This file is part of Crosroads 1.75, 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.71, a load balancer and fail over + * This file is part of Crosroads 1.75, 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.71, a load balancer and fail over + * This file is part of Crosroads 1.75, 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.71, a load balancer and fail over + * This file is part of Crosroads 1.75, 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.71, a load balancer and fail over + * This file is part of Crosroads 1.75, 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/strnstr.c b/src/lib/strnstr.c @@ -0,0 +1,35 @@ +/************************************************************************* + * This file is part of Crosroads 1.75, 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" + +#if HAVE_STRNSTR == 0 +char *strnstr (char const *big, char const *little, unsigned len) { + int i, max, llen; + + /* Check that we have strings */ + if (!big) + return (0); + if (!little) + return ( (char*) big); + + /* Get lengths */ + llen = strlen(little); + max = strlen(big) - llen; + + /* Check that big is bigger */ + if (max < 1) + return (0); + + /* Do the search */ + for (i = 0; i <= max; i++) + if (!strncmp (big + i, little, llen)) + return ((char*)(big + i)); + + /* Nothing found... */ + return (0); +} +#endif diff --git a/src/lib/strprintf.c b/src/lib/strprintf.c @@ -1,5 +1,5 @@ /************************************************************************* - * This file is part of Crosroads 1.71, a load balancer and fail over + * This file is part of Crosroads 1.75, 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/strupr.c b/src/lib/strupr.c @@ -1,5 +1,5 @@ /************************************************************************* - * This file is part of Crosroads 1.71, a load balancer and fail over + * This file is part of Crosroads 1.75, 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.71, a load balancer and fail over + * This file is part of Crosroads 1.75, 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.71, a load balancer and fail over + * This file is part of Crosroads 1.75, 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.71, a load balancer and fail over + * This file is part of Crosroads 1.75, 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.71, a load balancer and fail over + * This file is part of Crosroads 1.75, 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.71, a load balancer and fail over + * This file is part of Crosroads 1.75, 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.71, a load balancer and fail over + * This file is part of Crosroads 1.75, 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.71, a load balancer and fail over + * This file is part of Crosroads 1.75, a load balancer and fail over * utility for TCP. Copyright (c) Karel Kubat, distributed under GPL. * Visit http://crossroads.e-tunity.com for information. *************************************************************************/ @@ -27,9 +27,8 @@ void tcpserve (int server_sock) { if ( (pid = fork()) < 0 ) error ("Fork failed: %s", strerror(errno)); else if (!pid) { - if (!leave_proctitle) - setproctitle ("crossroads - Service %s: wakeup", - activeservice->name); + set_program_title ("crossroads - Service %s: wakeup", + activeservice->name); wakeup_handler(); } else { msg ("Service %s: started wakeup handler at pid %d", @@ -115,9 +114,12 @@ void tcpserve (int server_sock) { /* Leave it alone if there are no back ends or if we exceed * the max allowed clients. IN THAT CASE WE RETURN so that * runservice() may close the listener socket, sleep, and - * create a new one. + * create a new one. Exception is when the service has configured an + * external dispatcher: in that case our backend count is not + * reliable, and the external dispatcher may decide otherwise.. */ - if (! backend_count()) { + if (activeservice->dispatchtype != ds_externalhandler && + backend_count() == 0) { warning ("Service %s: no back ends available", activeservice->name); close (new); @@ -137,9 +139,11 @@ void tcpserve (int server_sock) { counter += 8, cp = strtok_r (0, ".", &last)) { if (sscanf (cp, "%u", &octet) > 0) { client_ip_nr |= (octet << counter); + /* msg ("Service %s: Client IP part 0x%2.2x (%d), " "hex client so far: 0x%8.8x", activeservice->name, octet, octet, client_ip_nr); + */ } } free (tmp); @@ -188,9 +192,11 @@ void tcpserve (int server_sock) { msg ("Service %s: About to choose a back end", activeservice->name); choose_backend(); - if (current_backend < 0) + if (current_backend < 0) { error ("Service %s: Could not select a back end", activeservice->name); + close (new); + } /* Connect to the backend. If this fails then we'll sleep * and re-enter the backend selection loop instead of returning. @@ -212,10 +218,9 @@ void tcpserve (int server_sock) { program_stage = stage_serving; for (i = 0; relevant_sigs[i]; i++) signal (relevant_sigs[i], interrupt); - if (!leave_proctitle) - setproctitle ("crossroads - Service %s: serving %s to %s", - activeservice->name, client_ip, - activeservice->backend[current_backend].name); + set_program_title ("crossroads - Service %s: serving %s to %s", + activeservice->name, client_ip, + activeservice->backend[current_backend].name); /* Child branch: piggyback to and fro. * This one never returns. */ diff --git a/src/lib/thruputlog.c b/src/lib/thruputlog.c @@ -1,5 +1,5 @@ /************************************************************************* - * This file is part of Crosroads 1.71, a load balancer and fail over + * This file is part of Crosroads 1.75, a load balancer and fail over * utility for TCP. Copyright (c) Karel Kubat, distributed under GPL. * Visit http://crossroads.e-tunity.com for information. *************************************************************************/ @@ -18,15 +18,9 @@ void thruputlog (unsigned char const *buf, int len, CopyDirection dir) { return; /* Initialize timer if necessary. Get current time. */ - if (! d_start) { - if (gettimeofday (&tv, 0)) - error ("Failed to get the time of day: %s\n", - strerror(errno)); - d_start = tv.tv_sec * 1000000 + tv.tv_usec; - } - if (gettimeofday (&tv, 0)) - error ("Failed to get the time of day: %s\n", strerror(errno)); - d_now = tv.tv_sec * 1000000 + tv.tv_usec; + if (!d_start) + d_start = timeofday(); + d_now = timeofday(); /* Get a handle on the reporting log. */ if ( (! (f = fopen (activeservice->backend[current_backend].thruputfile, @@ -46,10 +40,11 @@ void thruputlog (unsigned char const *buf, int len, CopyDirection dir) { #endif /* Report the activity. */ - fprintf (f, "%7.7d %15f %c ", + fprintf (f, "%7.7d %15f %c %8d ", getpid(), - (d_now - d_start) / 1000000, - dir == dir_client_to_server ? 'C' : 'B'); + d_now - d_start, + dir == dir_client_to_server ? 'C' : 'B', + len); for (i = 0; i < 100 && i < len; i++) fputc (isprint (buf[i]) ? buf[i] : '.', f); fputc ('\n', f); diff --git a/src/lib/timeofday.c b/src/lib/timeofday.c @@ -0,0 +1,17 @@ +/************************************************************************* + * This file is part of Crosroads 1.75, 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" + +double timeofday () { + struct timeval tv; + double ret; + + if (gettimeofday (&tv, 0)) + error ("Failed to get the time of day: %s", strerror(errno)); + ret = (double)tv.tv_sec + (double)tv.tv_usec / 1000000; + return (ret); +} diff --git a/src/lib/trafficlog.c b/src/lib/trafficlog.c @@ -1,5 +1,5 @@ /************************************************************************* - * This file is part of Crosroads 1.71, a load balancer and fail over + * This file is part of Crosroads 1.75, 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.71, a load balancer and fail over + * This file is part of Crosroads 1.75, 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.71, a load balancer and fail over + * This file is part of Crosroads 1.75, 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.71, a load balancer and fail over + * This file is part of Crosroads 1.75, a load balancer and fail over * utility for TCP. Copyright (c) Karel Kubat, distributed under GPL. * Visit http://crossroads.e-tunity.com for information. *************************************************************************/ diff --git a/src/lib/usage.c b/src/lib/usage.c @@ -1,5 +1,5 @@ /************************************************************************* - * This file is part of Crosroads 1.71, a load balancer and fail over + * This file is part of Crosroads 1.75, a load balancer and fail over * utility for TCP. Copyright (c) Karel Kubat, distributed under GPL. * Visit http://crossroads.e-tunity.com for information. *************************************************************************/ diff --git a/src/lib/usage.txt b/src/lib/usage.txt @@ -23,18 +23,20 @@ Usage: Supported flags: -a: Logs starting and finishing activity to syslog - -b: Writes binary configuration to stdout (debugging only) + -b: Writes binary options and 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, default %d (sec) + -h: Logs timings of HTTP processing to syslog -l FAC: Specifies the openlog(3) facility to use when logging. Default is LOG_DAEMON. Allowed values are 0..7 for LOG_LOCAL0 to LOG_LOCAL7. -m PERM: Sets permissions for shm access to PERM, which is an octal number. Defaults to 0644. + -P: Parser and lexer actions will be verbose (debugging only) -p: Process title will not be altered; 'ps' will show 'crossroads-daemon' instead of custom title -s: Sloppy binding to the listen port of each service (if the port @@ -45,4 +47,4 @@ Supported flags: -v: Enables verbosity upon startup. Other verbosity (services and back ends) is controlled in the configuration. -V: Shows the version ID and stops. - -?, -h: Shows this message. + -?: Shows this message. diff --git a/src/lib/vsyslog.c b/src/lib/vsyslog.c @@ -1,5 +1,5 @@ /************************************************************************* - * This file is part of Crosroads 1.71, a load balancer and fail over + * This file is part of Crosroads 1.75, 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.71, a load balancer and fail over + * This file is part of Crosroads 1.75, 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.71, a load balancer and fail over + * This file is part of Crosroads 1.75, 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.71, a load balancer and fail over + * This file is part of Crosroads 1.75, a load balancer and fail over * utility for TCP. Copyright (c) Karel Kubat, distributed under GPL. * Visit http://crossroads.e-tunity.com for information. *************************************************************************/ @@ -10,6 +10,6 @@ void writelog (int prio, char const *fmt, ...) { va_start (args, fmt); if (!logstarted++) - openlog ("crossroads", LOG_PID, log_facility); + openlog ("crossroads", LOG_PID, opt.log_facility); vsyslog (prio, fmt, args); } diff --git a/src/lib/xcalloc.c b/src/lib/xcalloc.c @@ -1,5 +1,5 @@ /************************************************************************* - * This file is part of Crosroads 1.71, a load balancer and fail over + * This file is part of Crosroads 1.75, 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.71, a load balancer and fail over + * This file is part of Crosroads 1.75, 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.71, a load balancer and fail over + * This file is part of Crosroads 1.75, 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.71, a load balancer and fail over + * This file is part of Crosroads 1.75, 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.71, a load balancer and fail over + * This file is part of Crosroads 1.75, 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.71, a load balancer and fail over + * This file is part of Crosroads 1.75, 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 @@ -1,106 +0,0 @@ - /* Parse the command line options. - * This file gets included from crossroads AND crossroads-daemon. - * NOTE: When changing the options list, remember to update: - * - src/lib/usage.txt - * - doc/main/using.yo - * - doc/man/crossroads.yo - */ - while ( (opt = getopt (argc, argv, "bB:?c:fhvi:Val:stCm:xd:X:p")) > 0 ) - switch (opt) { - case 'a': - log_activity++; - break; - case 'b': - #ifdef TARGET_CROSSROADS - msg ("Parsing configuration %s", config_file); - parser_open (config_file); - parser_run(); - parser_close(); - config_write (1); - exit (0); - #endif - break; - case 'B': - tcp_bufsz = atoi (optarg); - break; - case 'c': - config_file = optarg; - break; - case 'd': - dns_cachettl = atoi (optarg); - break; - case 'v': - flag_verbose++; - break; - case 'i': - iflag_present++; - break; - case 'l': - switch (atoi (optarg)) { - case 0: - log_facility = LOG_LOCAL0; - break; - case 1: - log_facility = LOG_LOCAL1; - break; - case 2: - log_facility = LOG_LOCAL2; - break; - case 3: - log_facility = LOG_LOCAL3; - break; - case 4: - log_facility = LOG_LOCAL4; - break; - case 5: - log_facility = LOG_LOCAL5; - break; - case 6: - log_facility = LOG_LOCAL6; - break; - case 7: - log_facility = LOG_LOCAL7; - break; - default: - #ifdef TARGET_CROSSROADS - usage(); - #else - error ("Bad invocation of crossroads-daemon"); - #endif - } - break; - case 'm': - shmperm = strtol (optarg, 0, 8); - break; - case 's': - sloppyportbind++; - break; - case 't': - tabular_status++; - break; - case 'x': - xml_status++; - break; - case 'X': - xml_xslt = optarg; - break; - case 'C': - #ifdef TARGET_CROSSROADS - show_config(); - #endif - exit (0); - case 'p': - leave_proctitle++; - break; - case 'V': - puts (VER); - exit (0); - case '?': - case 'h': - default: - #ifdef TARGET_CROSSROADS - usage (); - #else - error ("Bad invocation of crossroads-daemon"); - #endif - } diff --git a/test/Makefile b/test/Makefile @@ -6,12 +6,14 @@ foo: hashtest @echo @for f in t*.conf ; do \ echo "Testing $$f: should succeed" ; \ + echo "TEST: ../src/crossroads/crossroads -vc $$f services" ; \ ../src/crossroads/crossroads -vc $$f services || exit 1 ; \ echo "$$f succeeded, good." ; \ echo ; \ done @for f in bad*.conf ; do \ echo "Testing $$f: should fail" ; \ + echo "TEST: ../src/crossroads/crossroads -vc $$f services" ; \ ../src/crossroads/crossroads -vc $$f services && exit 1 ; \ echo "$$f failed, good." ; \ echo ; \ diff --git a/test/bad22.conf b/test/bad22.conf @@ -0,0 +1,8 @@ +/* A back end with a httptiminglog directive, but the service isn't http */ +service test { + port 2000; + backend one { + server localhost:2001; + httptiminglog /tmp/logfile; + } +} diff --git a/test/extdispatcher b/test/extdispatcher @@ -0,0 +1,14 @@ +#!/usr/bin/perl + +use strict; + +sub msg { + open (my $of, ">>/tmp/extdispatcher.log") or return; + print $of (@_); +} + +# Main +msg ("Run started, arguments: @ARGV\n"); + +# Reply that backend "one" is the right one to choose. +print ("one\n"); diff --git a/test/extdispatcher.conf b/test/extdispatcher.conf @@ -0,0 +1,19 @@ +/* Test of an external dispatcher */ + +#define DEBUG on + +service test { + port 20000; + verbosity DEBUG; + dispatchmode externalhandler + "/usr/local/src/crossroads/test/extdispatcher %r %s"; + + backend one { + server localhost:20001; + verbosity DEBUG; + } + backend two { + server localhost:20002; + verbosity DEBUG; + } +} diff --git a/test/maxcon.conf b/test/maxcon.conf @@ -0,0 +1,27 @@ +/* Test of 'maxconnections' on a client level. + * Each new connection must be handled by a different client, until + * the connections are exhausted. */ + +#define DEBUG on + +service threeallowed { + port 2222; + verbosity DEBUG; + revivinginterval 3; + + backend v01 { + server localhost:22; + maxconnections 1; + verbosity DEBUG; + } + backend v02 { + server localhost:22; + maxconnections 1; + verbosity DEBUG; + } + backend v03 { + server localhost:22; + maxconnections 1; + verbosity DEBUG; + } +} diff --git a/tools/c-conf b/tools/c-conf @@ -4,7 +4,9 @@ use strict; use Getopt::Std; # Globals -my $VER = "1.10"; +my $VER = "1.11"; +# 1.11 [KK 2008-01-14] Added /opt/local/{lib,include} to the standard libs. +# Also added /sw # 1.10 [KK 2007-08-29] Added libvariable01 and flag -l. Flags -l/L get # used upon libfunction/libvariable checks. # 1.09 [KK 2007-06-13] Added 'lib64' variants to libdirs, for 64bit Linux @@ -24,13 +26,19 @@ my $VER = "1.10"; # Configuration my @def_headerdirs = ('/usr/include', '/usr/local/include', + '/opt/local/include', + '/sw/include', "$ENV{HOME}/include", ); my @def_libdirs = ('/usr/lib', '/usr/lib64', - '/usr/local/lib', + '/usr/local/lib', '/usr/local/lib64', + '/opt/local/lib', + '/opt/local/lib64', '/usr/ucblib', + '/sw/lib', + '/sw/lib64', "$ENV{HOME}/lib", ); my @c_compilers = ('gcc', 'cc');