crossroads

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

crossroads.man (109280B)


      1 .TH "Crossroads 1\&.23" "2005, 2006, ff\&."
      2 .PP
      3 .SH "Crossroads 1\&.23"
      4 .SH "Karel Kubat"
      5 .SH "e-tunity"
      6 .SH "2005, 2006, ff\&."
      7 
      8 .PP 
      9 
     10 .SH "1: Introduction"
     11 Crossroads is a daemon that basically accepts TCP connections
     12 at preconfigured ports, and given a list of \&'back ends\&'
     13 distributes each incoming connection to one of the back ends,
     14 so that a client request is
     15 served\&. Additionally, crossroads maintains an internal
     16 administration of the back end connectivity: if a back end isn\&'t
     17 usable, then the client request is handled using another back
     18 end\&. Crossroads will then periodically check whether a previously not
     19 usable back end has come to life yet\&. Also, crossroads can select
     20 back ends by estimating the load, so that balancing is achieved\&.
     21 .PP 
     22 Using this approach, crossroads serves as load balancer and fail over
     23 utility\&. Crossroads will very likely not be as reliable as
     24 hardware based balancers, since it always will require a server to
     25 run on\&. This server, in turn, may become a new Single Point of
     26 Failure (SPOS)\&.  However, in situations where cost efficiency is an issue,
     27 crossroads may be a good choice\&. Furthermore, crossroads can be
     28 deployed in situations where a hardware based balancing already
     29 exists and augmenting service reliability is needed\&. Or, crossroads may be
     30 run off a diskless system, which again improves reliability of the
     31 underlying hardware\&.
     32 .PP 
     33 This document describes how to use crossroads, how to configure it
     34 in order to increase the reliability of your systems, and how to
     35 compile the program from its sources\&. 
     36 .PP 
     37 
     38 .SH "1\&.1: Obtaining Crossroads"
     39 
     40 .PP 
     41 As quick reference, here are some important URL\&'s for Crossroads:
     42 .PP 
     43 .IP o 
     44 http:/crossroads\&.e-tunity\&.com is the site that serves
     45 Crossroads\&. You can browse this at leisure
     46 for documentation, sources, and so on\&.
     47 .IP 
     48 .IP o 
     49 http://freshmeat\&.net/projects/crossr is the
     50 Freshmeat announcement page\&.
     51 .IP 
     52 .IP o 
     53 svn://svn\&.e-tunity\&.com/crossroads is the SVN
     54 repository; anonymous reading (fetching) is allowed\&. In order
     55 to commit changes, mail me for
     56 credentials\&.
     57 .PP 
     58 
     59 .SH "1\&.2: Copyright and Disclaimer"
     60 
     61 .PP 
     62 Crossroads is distributed as-is, without assumptions of fitness
     63 or usability\&. You are free to use crossroads to your
     64 liking\&. It\&'s free, and as with everything that\&'s free: there\&'s
     65 also no warranty\&.
     66 .PP 
     67 You are allowed to make modifications to the source code of
     68 crossroads, and you are allowed to (re)distribute crossroads, as
     69 long as you include this text, all sources, and if applicable: all
     70 your modifications, with each distribution\&.
     71 .PP 
     72 While you are allowed to make any and all changes to the sources,
     73 I would appreciate hearing about them\&. If the changes concern new
     74 functionality or bugfixes, then I\&'ll include them in a next
     75 release, stating full credits\&. If you want to seriously contribute (to
     76 which you are heartily encouraged), then mail me and I\&'ll get you
     77 access to the Crossroads SVN repository, so that you can update and
     78 commit as you like\&.
     79 .PP 
     80 
     81 .SH "1\&.3: Terminology"
     82 
     83 .PP 
     84 Throughout this document, the following terms are used: \e (Many
     85 more meanings of the terms will exist -- yes, I am aware of that\&. I\&'m
     86 using the terms here in a very strict sense\&.)
     87 .PP 
     88 .IP "A client"
     89 is a process that initiates a network connection
     90 to get contact with some service\&. 
     91 .IP "A service"
     92 or \fBserver process\fP or \fBlistener\fP
     93 is a central application
     94 that accepts network connections from clients and sevices
     95 them\&.
     96 .IP "Back ends"
     97 are locations where crossroads looks in
     98 order to service its clients\&. Crossroads sits \&'in between\&'
     99 and does its tricks\&. Therefore, as far as the back ends
    100 are concerned, crossroads behaves like a client\&. As far as
    101 the true client is concerned, crossroads behaves like the
    102 service\&. The communication is however transparent: neither
    103 client nor back end are aware of the middle position of
    104 crossroads\&.
    105 .IP "A connection"
    106 is a network conversation between client and service,
    107 where data are transferred to and fro\&. As
    108 far as crossroads is concerned, success means that a
    109 connection can be established without errors on
    110 the network level\&. Crossroads isn\&'t aware of service
    111 pecularities\&. E\&.g\&., when a webserver answers \f(CWHTTP/1\&.0
    112 500 Server Error\fP then crossroads will see this as a
    113 succesful connection, though the user behind a browser may
    114 think otherwise\&.
    115 .IP "Back end selection algorithms"
    116 are methods by which
    117 crossroads determines which back end it will talk to
    118 next\&. Crossroads has a number of built-in algorithms,
    119 which may be configured per service\&.
    120 .IP "Back end states"
    121 are the statusses of each back end that
    122 is known to crossroads\&. A back end may be available,
    123 (temporarily) unavailble or truly down\&. When a back end is
    124 temporarily unavailable, then crossroads will periodically
    125 check whether the back end has come to life yet (that is,
    126 if configured so)\&.
    127 .IP "A spike"
    128 is a sudden increase in activity, leading to
    129 extra load on a given service\&. When crossroads is in
    130 effect and when the spike occurs in one connection,
    131 then obviously the spike will also appear at one
    132 of the back ends\&. However, crossroads will see the spike
    133 and will make sure that a subsequent request goes to an
    134 other back end\&. In contrast, when several connections
    135 arrive simultaneously and cause a spike, then crossroads
    136 will be able to distribute the connections over several
    137 back ends, thereby \&'flattening out\&' the increase\&.
    138 .IP "Load balancing"
    139 means that incoming client requests are
    140 distributed over more than just one back end (which wouldn\&'t be the
    141 case if you wouldn\&'t be running crossroads)\&. Enabling load
    142 balancing is nothing more than duplicating services over
    143 more than one back end, and having something (in this
    144 case: crossroads) distribute the requests, so that per
    145 back end the load doesn\&'t get too high\&.
    146 .IP "An HTTP session"
    147 is a series of separate network connections
    148 that originate from one browser\&. E\&.g\&., to fill the display
    149 with text and images, the browser hits a website several times\&.
    150 An HTTP session may even span several
    151 screens\&. E\&.g\&., a website registration dialog may involve 3
    152 screens that when called from the same browser, 
    153 form a logical group of some sort\&.
    154 .IP "Headers"
    155 or \fBheader lines\fP are specific parts of an HTTP
    156 message\&. Crossroads has directives to add or modify
    157 headers that are part of the request that a browser sends
    158 to server, or those that are part of the server\&.
    159 .IP "Session stickiness"
    160 means that when a browser starts an
    161 HTTP dialog, the balancer makes sure that it \&'sticks\&' to
    162 the same back end (i\&.e\&., subsequent requests from the
    163 browser are forced to go to the same back end, instead of
    164 being balanced to other ones)\&.
    165 .IP "Back end usage"
    166 is measured by crossroads in order to be
    167 able to determine back end selection\&. Crossroads stores
    168 information about the number of active connections, the
    169 transferred bytes and 
    170 about the connection duration\&. These numbers can be used to
    171 estimate which back end is the least used -- and
    172 therefore, presumably, the best candidate for a new
    173 request\&.
    174 .IP "Fail over"
    175 is almost always used when load balancing is in
    176 effect\&. The distributor of client requests (crossroads of
    177 course) can also monitor back ends, so that incase a back
    178 end is \&'down\&', it is no longer accessed\&.
    179 .IP "Service downtime"
    180 normally occurs when a service is
    181 switched off\&. Downtime is obviously avoided when fail over
    182 is in effect: a back end can be taken out of service in a
    183 controlled manner, without any client noticing it\&.
    184 
    185 .PP 
    186 
    187 .SH "1\&.4: Porting issues for pre-1\&.21 installations"
    188 
    189 .PP 
    190 As of version 1\&.21, the event-hook directives \f(CWonsuccess\fP and
    191 \f(CWonfailure\fP no longer exists\&.
    192 .PP 
    193 .IP o 
    194 Please replace \f(CWonsuccess\fP by \f(CWonstart\fP;
    195 .IP o 
    196 Please replace \f(CWonfailure\fP bu \f(CWonfail\fP;
    197 .IP o 
    198 Note that there is a new hook \f(CWonend\fP\&.
    199 .PP 
    200 The commands that are run via \f(CWonstart\fP, \f(CWonend\fP or \f(CWonfail\fP
    201     are subject to format expansion; e\&.g\&., \f(CW%1w\fP is expanded to the
    202     weight of the first back end, etc\&.\&. See section ?? for details\&.
    203 .PP 
    204 
    205 .SH "1\&.5: Porting issues for pre-0\&.26 installations"
    206 
    207 .PP 
    208 As of version 0\&.26 the syntax of the configuration file has
    209 changed\&. In particular:
    210 .PP 
    211 .IP o 
    212 The keyword \f(CWmaxconnections\fP is now used instead of
    213 \f(CWmaxclients\fP;
    214 .IP o 
    215 The keyword \f(CWconnectiontimeout\fP is now used instead of
    216 \f(CWsessiontimeout\fP\&.
    217 .PP 
    218 Therefore when converting configuration files to the new syntax,
    219 the above keywords must be changed\&. (The reason for these changes
    220 is that 0\&.26 introduces \fIsticky HTTP sessions\fP that span
    221 multiple TCP connections, and the term
    222 \fIsession\fP is used strictly in that sense -- and no longer for a
    223 TCP connection\&.)
    224 .PP 
    225 
    226 .SH "1\&.6: Porting issues for pre-1\&.08 installations"
    227 
    228 .PP 
    229 As of version 1\&.08, the following directives no longer are
    230 supported:
    231 .PP 
    232 .IP o 
    233 \f(CWinsertstickycookie\fP was replaced by the more generic
    234 directive \f(CWaddclientheader\fP\&. E\&.g\&., instead of 
    235 .br 
    236 \f(CWinsertstickycookie "XRID=100; Path=/";\fP 
    237 .br 
    238 the syntax is now 
    239 .br 
    240 \f(CWaddclientheader "Set-Cookie: XRID=100; Path=/";\fP
    241 .IP 
    242 .IP o 
    243 \f(CWinsertrealip\fP was replaced by the more generic
    244 directive \f(CWsetserverheader\fP\&. E\&.g\&., instead of 
    245 .br 
    246 \f(CWinsertrealip on;\fP 
    247 .br 
    248 the syntax is now 
    249 .br 
    250 \f(CWsetserverheader "XR-Real-IP: %r";\fP 
    251 .br 
    252 This incidentally also makes it possible to change the header
    253 name (here: \f(CWXR-Real-IP\fP)\&.
    254 .PP 
    255 
    256 .SH "2: Installation for the impatient"
    257 For the impatient, here\&'s the very-quick-but-very-superficial recipy
    258 for getting crossroads up and running:
    259 .PP 
    260 .IP o 
    261 If you don\&'t have SVN or don\&'t want to use it:
    262 .IP 
    263 .IP o 
    264 Obtain the crossroads source archive at
    265 http://crossroads\&.e-tunity\&.com\&.
    266 .IP 
    267 .IP o 
    268 Change-dir to a \&'sources\&' directory on your system and
    269 unpack the archive\&.
    270 .IP 
    271 .IP o 
    272 Change-dir into the create directory \f(CWcrossroads/\fP\&.
    273 .IP 
    274 .IP o 
    275 If you have SVN and want to go for the newest snapshot:
    276 .IP 
    277 .IP o 
    278 Get the latest sources and snapshots using SVN from 
    279 .br 
    280 \f(CWsvn://svn\&.e-tunity\&.com/crossroads\fP\&.
    281 .IP 
    282 .IP o 
    283 You\&'ll find the newest alpha version under
    284 \f(CWcrossroads/trunk\fP and the stable versions under
    285 \f(CWcrossroads/tags\fP,
    286 e\&.g\&. \f(CWcrossroads/tags/release-1\&.00\fP\&.
    287 .IP 
    288 .IP o 
    289 Choose which you want to use: the latest stable
    290 release, or the bleeding edge alpha? In the former case,
    291 change-dir to \f(CWcrossroads/tags/release-\fP\fIX\&.YY\fP, where
    292 \fIX\&.YY\fP is a release ID\&. In the latter case, change-dir to
    293 \f(CWcrossroads/trunk\fP\&.
    294 .IP 
    295 .IP o 
    296 Type \f(CWmake install\fP\&. This installs the crossroads
    297 binary into \f(CW/usr/local/bin/\fP\&. If the compilation doesn\&'t
    298 work on your system, check \f(CWetc/Makefile\&.def\fP for hints\&.
    299 .IP 
    300 .IP o 
    301 Create a file \f(CW/etc/crossroads\&.conf\fP\&. In it state
    302 something like:
    303 .IP 
    304 .nf 
    305 service www {
    306     port 80;
    307     revivinginterval 15;
    308     backend one {
    309         server 10\&.1\&.1\&.100:80;
    310     }
    311     backend two {
    312         server 10\&.1\&.1\&.101:80;
    313     }
    314 }
    315 .fi 
    316 
    317 .IP 
    318 That\&'s off course assuming that you want to balance HTTP on
    319 port 80 to two back ends at 10\&.1\&.1\&.100 and 10\&.1\&.1\&.101\&.
    320 .IP 
    321 .IP o 
    322 Type \f(CWcrossroads start\fP\&.
    323 .IP 
    324 .IP o 
    325 Surf to the machine where crossroads is running\&. You will
    326 see the pages served by the back ends 10\&.1\&.1\&.100 or
    327 10\&.1\&.1\&.101\&.
    328 .IP 
    329 .IP o 
    330 To monitor the status of crossroads, type \f(CWcrossroads
    331 status\fP\&.
    332 
    333 .PP 
    334 
    335 .SH "3: Using Crossroads"
    336 Crossroads is started from the commandline, and highly depends on
    337 \f(CW/etc/crossroads\&.conf\fP (the default configuration file)\&. It 
    338 supports a number of flags (e\&.g\&., to overrule the location of the
    339 configuration file)\&. The actual usage information is always obtained
    340 by typing \f(CWcrossroads\fP without any arguments\&. Crossroads then
    341 displays the allowed arguments\&.
    342 .PP 
    343 
    344 .SH "3\&.1: General Commandline Syntax"
    345 
    346 .PP 
    347 This section shows the most basic usage\&. As said above, start
    348 \f(CWcrossroads\fP without arguments to view the full listing of options\&.
    349 .PP 
    350 .IP o 
    351 \f(CWcrossroads start\fP and \f(CWcrossroads stop\fP are typical
    352 actions that are run from system startup scripts\&. The
    353 meaning is self-explanatory\&.
    354 .IP o 
    355 \f(CWcrossroads restart\fP is a combination of the former
    356 two\&. Beware that a restart may cause discontinuity in
    357 service; it is just a shorthand for typing the \&'stop\&' and
    358 \&'start\&' actions after one another\&.
    359 .IP o 
    360 \f(CWcrossroad status\fP reports on each running
    361 service\&. Per service, the state of each back end is
    362 reported\&.
    363 .IP o 
    364 \f(CWcrossroads tell\fP \fIservice backend state\fP is a
    365 command line way of telling crossroads that a given back
    366 end, of a given service, is in a given state\&. Normally
    367 crossroads maintains state information itself, but by
    368 using \f(CWcrossroads tell\fP, a back end can be e\&.g\&. taken
    369 \&'off line\&' for servicing\&.
    370 .IP o 
    371 \f(CWcrossroads configtest\fP tells you whether the
    372 configuration is syntactially correct\&.
    373 .IP o 
    374 \f(CWcrossroads services\fP reports on the configured 
    375 services\&. In contrast to \f(CWcrossroads status\fP, this
    376 option only shows what\&'s configured -- not what\&'s up and
    377 running\&. Therefore, \f(CWcrossroads services\fP doesn\&'t
    378 report on back end states\&.
    379 .IP o 
    380 \f(CWcrossroads sampleconf\fP shows a sample configuration on
    381 screen\&. A good way of quicky viewing the configuration
    382 file syntax, or of getting a start for your own
    383 configuration \f(CW/etc/crossroads\&.conf\fP\&.
    384 
    385 .PP 
    386 
    387 .SH "3\&.2: Logging-related options"
    388 
    389 .PP 
    390 Two \&'flags\&' of Crossroads are specifically logging-related\&. This
    391 section elaborates on these flags\&.
    392 .PP 
    393 First, there\&'s flag \f(CW-a\fP\&. When present, the start and end of
    394 activity is logged using statements like
    395 .PP 
    396 \fIYYYY-MM-DD HH/MM/SS starting http from 61\&.45\&.32\&.189 to 10\&.1\&.1\&.1\fP
    397 
    398 .PP 
    399 Similarly, there are \&'ending\&' statements\&. Using this flag and 
    400 scanning your logs for these statements may be helpful in quickly
    401 determining your system load\&.
    402 .PP 
    403 Second, there\&'s flag \f(CW-l\fP\&. This flag selects the \&'facility\&' of
    404 logging and defaults to \f(CWLOG_DAEMON\fP\&. You can supply a number
    405 between 0 and 7 to flag \f(CW-l\fP to select \f(CWLOG_LOCAL0\fP to
    406 \f(CWLOG_LOCAL7\fP\&. This would separate the Crossroads-related logging
    407 from other streams\&. Here\&'s a very short guide; please read your Unix
    408 manpages of \f(CWsyslogd\fP for more information\&.
    409 .PP 
    410 .IP o 
    411 First edit \f(CW/etc/syslog\&.conf\fP and add a line:
    412 .IP 
    413 .nf 
    414 local7\&.*   /var/log/crossroads\&.log
    415 .fi 
    416 
    417 .IP 
    418 That instructs \f(CWsyslogd\fP to send \f(CWLOG_LOCAL7\fP requests to the
    419 logfile \f(CW/var/log/crossroads\&.log\fP\&.
    420 .IP 
    421 .IP o 
    422 Next, restart \f(CWsyslogd\fP\&. On most Unices that\&'s done by
    423 issuing \f(CWkillall -1 syslogd\fP\&. (As a side-note, I tried this once
    424 on an Bull/AIX system, and the box just shut down\&. The \f(CWkillall\fP
    425 command killed every process\&.\&.\&.)
    426 .IP 
    427 .IP o 
    428 Now start \f(CWcrossroads\fP with the flag \f(CW-l7\fP\&.
    429 .IP 
    430 .IP o 
    431 Finally, monitor \f(CW/var/log/crossroads\&.log\fP for Crossroads\&'
    432 messages\&.
    433 .PP 
    434 
    435 .SH "3\&.3: Reloading Configurations"
    436 
    437 .PP 
    438 Crossroads doesn\&'t support the reloading of a configuration while
    439 running (such as other programs, e\&.g\&. Apache do)\&. There are various
    440 technical reasons for this\&.
    441 .PP 
    442 However, external lists of allowed or denied IP addresses can be
    443 reloaded by sending a signal -1 (\f(CWSIGHUP\fP) to Crossroads\&. See
    444 section ?? for the details\&.
    445 .PP 
    446 
    447 .SH "4: The configuration"
    448 The configuration that crossroads uses is normally stored in the file
    449 \f(CW/etc/crossroads\&.conf\fP\&. This location can be overruled using the
    450 command line flag \f(CW-c\fP\&.
    451 .PP 
    452 This section explains the syntax of the configuration file, and what
    453 all settings do\&.
    454 .PP 
    455 
    456 .SH "4\&.1: General language elements"
    457 
    458 .PP 
    459 This section describes the general elements of the crossroads
    460 configuration language\&.
    461 .PP 
    462 
    463 .SH "4\&.1\&.1: Empty lines and comments"
    464 
    465 .PP 
    466 Empty lines are of course allowed in the
    467 configuration\&. Crossroads recognizes three formats of comment:
    468 .PP 
    469 .IP o 
    470 C-style, between \f(CW/*\fP and \f(CW*/\fP,
    471 .IP o 
    472 C++-style, starting with \f(CW//\fP and ending with the end
    473 of the text line;
    474 .IP o 
    475 Shell-style, starting with \f(CW#\fP and ending with the end
    476 of the text line\&.
    477 .PP 
    478 Simply choose your favorite editor and use the comment that \&'looks
    479 best\&'\&.\e (I favor C or C++ comment\&. My favorite editor \fIemacs\fP
    480 can be put in \f(CWcmode\fP and nicely highlight what\&'s comment and what\&'s
    481 not\&. And as a bonus it will auto-indent the configuration!)
    482 .PP 
    483 
    484 .SH "4\&.1\&.2: Keywords, numbers, identifiers, generic strings"
    485 
    486 .PP 
    487 In a configuration file, statements are identified by \fIkeywords\fP,
    488 such as \f(CWservice\fP, \f(CWverbosity\fP\&. These are reserved words\&.
    489 .PP 
    490 Many keywords require an \fIidentifier\fP as the argument\&. E\&.g, a
    491 service has a unique name, which must start with a letter or
    492 underscore, followed by zero or more letters, underscores, or
    493 digits\&. Therefore, in the statement \f(CWservice myservice\fP, the keyword is
    494 \f(CWservice\fP and the identifier is \f(CWmyservice\fP\&.
    495 .PP 
    496 Other keywords require a numeric argument\&. Crossroads knows only
    497 non-negative integer numbers, as in \f(CWport 8000\fP\&. Here, \f(CWport\fP is
    498 the keyword and \f(CW8000\fP is the number\&.
    499 .PP 
    500 Yet other keywords require \&'generic strings\&', such as hostname
    501 specifications or system commands\&. Such generic strings contain any
    502 characters (including white space) up to the terminating statement
    503 character \f(CW;\fP\&. If a string must contain a semicolon, then it must
    504 be enclosed in single or double quotes:
    505 .PP 
    506 .IP o 
    507 \f(CWThis is a string;\fP is a string that starts at \f(CWT\fP
    508 and ends with \f(CWg\fP
    509 .IP o 
    510 \f(CW"This is a string";\fP is the same, the double quotes
    511 are not necessary
    512 .IP o 
    513 \f(CW"This is ; a string";\fP has double quotes to protect
    514 the inner ;
    515 .PP 
    516 Finally, an argument can be a \&'boolean\&' value\&. Crossroads knows
    517 \f(CWtrue\fP, \f(CWfalse\fP, \f(CWyes\fP, \f(CWno\fP, \f(CWon\fP, \f(CWoff\fP\&. The keywords
    518 \f(CWtrue\fP, \f(CWyes\fP and \f(CWon\fP all mean the same and can be used
    519 interchangeably; as can the keywords \f(CWfalse\fP, \f(CWno\fP and \f(CWoff\fP\&.
    520 .PP 
    521 
    522 .SH "4\&.2: Service definitions"
    523 
    524 .PP 
    525 Service definitions are blocks in the configuration file that
    526 state what is for each service\&. A service definition starts with
    527 \f(CWservice\fP, followed by a unique identifier, and by statements in
    528 \f(CW{\fP and \f(CW}\fP\&. For example:
    529 .PP 
    530 .nf 
    531 // Definition of service \&'www\&':
    532 service www {
    533     \&.\&.\&.
    534     \&.\&.\&. // statements that define the
    535     \&.\&.\&. // service named \&'www\&'
    536     \&.\&.\&.
    537 }
    538 .fi 
    539 
    540 .PP 
    541 The configuration file can contain many service blocks, as long as the
    542 identifying names differ\&. The following list shows possible
    543 statements\&. Each statement must end with a semicolon, except for the
    544 \f(CWbackend\fP statement, which has is own block (more on this later)\&.
    545 .PP 
    546 
    547 .SH "4\&.2\&.1: type - Defining the service type"
    548 .IP "Description:"
    549 The \f(CWtype\fP statement defines how crossroads handles the stated
    550 service\&. There are currently two types: \f(CWany\fP and
    551 \f(CWhttp\fP\&. The type \f(CWany\fP means that crossroads doesn\&'t
    552 interpret the contents of a TCP stream, but only distributes streams
    553 over back ends\&. The type \f(CWhttp\fP means that crossroads has to
    554 analyze what\&'s in the messages, does magical HTTP header tricks, and
    555 so on -- all to ensure that multiple connections are treated as one
    556 session, or that the back end is notified of the client\&'s IP
    557 address\&.
    558 .IP 
    559 Unless you really need such special features, use the type \f(CWany\fP (the
    560 default), even for HTTP protocols\&.
    561 .IP "Syntax:"
    562 \f(CWtype\fP \fIspecifier\fP, where \fIspecifier\fP is \f(CWany\fP or
    563 \f(CWhttp\fP
    564 .IP "Default:"
    565 \f(CWany\fP
    566 
    567 .PP 
    568 
    569 .SH "4\&.2\&.2: port - Specifying the listen port"
    570 .IP "Description:"
    571 The \f(CWport\fP statement defines to which TCP port a service
    572 \&'listens\&'\&. E\&.g\&. \f(CWport 8000\fP says that this service will accept
    573 connections on port 8000\&.
    574 .IP "Syntax:"
    575 \f(CWport\fP \fInumber\fP
    576 .IP "Default:"
    577 There is no default\&. This is a required setting\&.
    578 
    579 .PP 
    580 
    581 .SH "4\&.2\&.3: bindto - Binding to a specific IP address"
    582 .IP "Description:"
    583 The \f(CWbindto\fP statement is used in situations where crossroads
    584 should only listen to the stated port at a given IP address\&. E\&.g\&.,
    585 \f(CWbindto 127\&.0\&.0\&.1\fP causes crossroads to \&'bind\&' the service only to
    586 the local IP address\&. Network connections from other hosts won\&'t be
    587 serviced\&. By default, crossroads binds a service to all presently
    588 active IP addresses at the invoking host\&.
    589 .IP "Syntax:"
    590 \f(CWbindto\fP \fIaddress\fP, where \fIaddress\fP is a numeric IP
    591 address, such as 127\&.0\&.0\&.1, or the keyword \f(CWany\fP\&.
    592 .IP "Default:"
    593 \f(CWany\fP
    594 
    595 .PP 
    596 
    597 .SH "4\&.2\&.4: verbosity - Controlling debug output"
    598 .IP "Description:"
    599 Verbosity statements  come in two forms: \f(CWverbosity on\fP or
    600 \f(CWverbosity off\fP\&. When \&'on\&', log messages to \f(CW/var/log/messages\fP
    601 are generated that show what\&'s going on\&.\e (Actually, the
    602 messages go to \f(CWsyslog(3)\fP, using facility \f(CWLOG_DAEMON\fP and
    603 priority \f(CWLOG_INFO\fP\&. In most (Linux) cases this will mean: output to
    604 \f(CW/var/log/messages\fP\&. On Mac OSX the messages go to
    605 \f(CW/var/log/system\&.log\fP\&.) The keyword \f(CWverbose\fP is an alias for
    606 \f(CWverbosity\fP\&.
    607 .IP "Syntax:"
    608 \f(CWverbosity\fP \fIsetting\fP or \f(CWverbose\fP \fIsetting\fP, where
    609 \fIsetting\fP is \f(CWtrue\fP, \f(CWyes\fP or \f(CWon\fP to turn 
    610 verbosity on; or \f(CWfalse\fP, \f(CWno\fP, \f(CWoff\fP to turn it off\&.
    611 .IP "Default:"
    612 \f(CWoff\fP
    613 
    614 .PP 
    615 
    616 .SH "4\&.2\&.5: dispatchmode - How are back ends selected"
    617 .IP "Description:"
    618  The dispatch mode controls how crossroads selects a back end from
    619      a list of active back ends\&. The below text shows the bare
    620      syntax\&. See section ?? for a textual explanation\&.
    621 .IP 
    622 The settings can be:
    623 .IP 
    624 .IP o 
    625 \f(CWdispatchmode roundrobin\fP: Simply the \&'next in line\&' is
    626 chosen\&. E\&.g, when 3 back ends are active, then the usage
    627 series is 1, 2, 3, 1, 2, 3, and so on\&.
    628 .IP 
    629 Roundrobin dispatching is the default method, when no
    630 \f(CWdispatchmode\fP statement occurs\&.
    631 .IP 
    632 .IP o 
    633 \f(CWdispatchmode random\fP: Random selection\&. Probably only
    634 for stress testing, though when used with weights (see below)
    635 it is a good distributor of new connections too\&.
    636 .IP 
    637 .IP o 
    638 \f(CWdispatchmode bysize [ over\fP \fIconnections\fP \f(CW]\fP:
    639 The next back end is the one
    640 that has transferred the least number of bytes\&. This
    641 selection mechanism assumes that the more bytes, the heavier
    642 the load\&.
    643 .IP 
    644 The modifier \f(CWover\fP \fIconnections\fP is optional\&. (The square
    645 brackets shown above are not part of the statement but
    646 indicate optionality\&.)  When given,
    647 the load is computed as an average of the last stated number of
    648 connections\&. When this modifier is absent, then the load is
    649 computed over all connections since startup\&.
    650 .IP 
    651 .IP o 
    652 \f(CWdispatchmode byduration [ over\fP \fIconnections\fP \f(CW]\fP:
    653 The next back end is the one
    654 that served connections for the shortest time\&. This mechanism
    655 assumes that the longer the connection, the heavier the load\&.
    656 .IP 
    657 .IP o 
    658 \f(CWdispatchmode byconnections\fP: The next back end is the one
    659 with the least active connections\&. This mechanism assumes that
    660 each connection to a back end represents load\&. It is usable
    661 for e\&.g\&. database connections\&.
    662 .IP 
    663 .IP o 
    664 \f(CWdispatchmode byorder\fP: The first back end is selected
    665 every time, unless it\&'s unavailable\&. In that case the second
    666 is taken, and so on\&.
    667 .IP 
    668 .IP o 
    669 \f(CWdispatchmode externalhandler\fP \fIprogram arguments\fP:
    670 This is a special mode, where an external program is delegated
    671 the responsibility to say which back end should be used
    672 next\&. In this case, Crossroads will call the external program,
    673 and this will of course be slower than one of the \&'built-in\&'
    674 dispatch modes\&. However, this is the ultimate escape when
    675 custom-made dispatch modes are needed\&.
    676 .IP 
    677 The dispatch mode that uses an \f(CWexternalhandler\fP is
    678         discussed separately in section ??\&.
    679 .IP 
    680 The selection algorithm is only used when clients are serviced that
    681 aren\&'t part of a sticky HTTP session\&. This is the case during:
    682 .IP 
    683 .IP o 
    684 all client requests of a service type \f(CWany\fP;
    685 .IP o 
    686 new sessions of a service type \f(CWhttp\fP\&.
    687 .IP 
    688 When type \f(CWhttp\fP is in effect and a session is underway, then the
    689 previously used back end is always selected -- regardless of
    690 dispatching mode\&.
    691 .IP 
    692 Your \&'right\&' dispatch mode will depend on the type of service\&. Given
    693 the fact that crossroads doesn\&'t know (and doesn\&'t care) how to
    694 estimate load from a network traffic stream, you have to choose an
    695 appropriate dispatch mode to optimize load balancing\&. In most cases,
    696 \f(CWroundrobin\fP or \f(CWbyconnections\fP will do the job just fine\&.
    697 .IP "Syntax:"
    698 \f(CWdispatchmode\fP \fImode\fP (see above for the modes), optionally
    699 followed by \f(CWover\fP \fInumber\fP, or when the \fImode\fP is
    700 \f(CWexternalhandler\fP, followed by \fIprogram\fP\&.
    701 .IP "Default:"
    702 \f(CWroundrobin\fP
    703 
    704 .PP 
    705 
    706 .SH "4\&.2\&.6: revivinginterval - Back end wakeup calls"
    707 .IP "Description:"
    708 A reviving interval definition is needed when crossroads
    709 determines that a back end is temporarily unavailable\&. This will
    710 happen when: 
    711 .IP 
    712 .IP o 
    713 The back end cannot be reached (network connection
    714 fails);
    715 .IP o 
    716 The network connection to the back end suddenly dies\&.
    717 .IP 
    718 An example of the definition is \f(CWrevivinginterval 10\fP\&. When this
    719 reviving interval is given, crossroads will check each 10 seconds
    720 whether unavailable back ends have woken up yet\&. A back end is
    721 considered awake when a network connection to that back end can
    722 succesfully be established\&.
    723 .IP "Syntax:"
    724 \f(CWrevivinginterval\fP \fInumber\fP, where the number is the interval
    725 in seconds\&.
    726 .IP "Default:"
    727 0 (no wakeup calls)
    728 
    729 .PP 
    730 
    731 .SH "4\&.2\&.7: maxconnections - Limiting concurrent clients at service level"
    732 .IP "Description:"
    733 The maximum number of connections is specified using
    734 \f(CWmaxconnections\fP\&. There is one argument; the number of concurrent
    735 established connections that may be active within one service\&.
    736 .IP 
    737 \&'Throttling\&' the number of connections is a way of preventing Denial of
    738 Service (DOS) attacks\&. Without a limit, numerous network connections
    739 may spawn so many server instances, that the service ultimately breaks
    740 down and becomes unavailable\&.
    741 .IP "Syntax:"
    742 \f(CWmaxconnections\fP \fInumber\fP, where the number specifies the
    743 maximum of concurrent connections to the service\&.
    744 .IP "Default:"
    745 0, meaning that all connections will be accepted\&.
    746 
    747 .PP 
    748 
    749 .SH "4\&.2\&.8: backlog - The TCP Back Log size"
    750 .IP "Description:"
    751 The TCP back log size is a number that controls how many
    752 \&'waiting\&' network connections may be queued, before a client simply
    753 cannot connect\&. The syntax is e\&.g\&. \f(CWbacklog 5\fP to cause crossroads
    754 to have 5 waiting connections for 1 active connection\&.
    755 The backlog queue shouldn\&'t be too
    756 high, or clients will experience timeouts before they can actually
    757 connect\&. The queue shouldn\&'t be too small either, because clients
    758 would be simply rejected\&. Your mileage may vary\&.
    759 .IP "Syntax:"
    760 \f(CWbacklog\fP \fInumber\fP
    761 .IP "Default:"
    762 0, which takes the operating system\&'s default
    763 value for socket back log size\&.
    764 
    765 .PP 
    766 
    767 .SH "4\&.2\&.9: shmkey - Shared Memory Access"
    768 .IP "Description:"
    769 Different Crossroads
    770 invocations must \&'know\&' of each others activity\&. E\&.g, \f(CWcrossroad
    771 status\fP must be able to get to the actual state information of all
    772 running services\&. This is internally implemented through shared
    773 memory, which is reserved using a key\&.
    774 .IP 
    775 Normally crossroads will supply a shared memory key, based on the
    776 service port and bitwise or-ed with a magic number\&. In situations
    777 where this conflicts with existing keys (of other programs, having
    778 their own keys), you may supply a chosen value\&.
    779 .IP 
    780 The actual key value doesn\&'t matter much, as long as it\&'s unique
    781 and as long as each invocation of crossroads uses it\&.
    782 .IP "Syntax:"
    783 \f(CWshmkey\fP \fInumber\fP
    784 .IP "Default:"
    785 0, which means that crossroads will \&'guess\&' its
    786 own key, based on TCP port and a magic number\&.
    787 
    788 .PP 
    789 
    790 .SH "4\&.2\&.10: allow* and deny* - Allowing or denying connections"
    791 .IP "Description:"
    792 Crossroads can allow or deny
    793 connections based on the IP address of a client\&. There are four
    794 directives that are relevant: \f(CWallowfrom\fP, \f(CWallowfile\fP,
    795 \f(CWdenyfrom\fP and \f(CWdenyfile\fP\&. When using \f(CWallowfrom\fP and
    796 \f(CWdenyfrom\fP then the IP addresses to allow or deny connections are
    797 stated in \f(CW/etc/crossroads\&.conf\fP\&.
    798 .IP 
    799 When \f(CWallow*\fP directives are used, then all connections are denied
    800 unless they match the stated allowed IP\&'s\&. When \f(CWdeny*\fP directives
    801 are used, then all connections are allowed unless they match the
    802 stated disallowed IP\&'s\&. When denying and allowing is both used,
    803 then the Crossroads checks the deny list first\&.
    804 .IP 
    805 The statements \f(CWallowfrom\fP and \f(CWdenyfrom\fP are followed by a
    806 list of filter specifications\&. The statements \f(CWallowfile\fP and
    807 \f(CWdenyfile\fP are followed by a filename; Crossroads will read
    808 filter specifications from those external files\&. In both cases,
    809 Crossroads obtains filter specifications and places them in its
    810 lists of allowed or denied IP addresses\&. The difference between
    811 specifying filters in \f(CW/etc/crossroads\&.conf\fP or in external
    812 files, is that Crossroads will reload the external files when it
    813 receives signal 1 (\f(CWSIGHUP\fP), as in \f(CWkillall -1 crossroads\fP\&.
    814 .IP 
    815 The filter specifications must obey the following syntax: it
    816 consists of up to 
    817 four numbers ranging from 0 to 255 and separated by a decimal
    818 sign\&. Optionally a slash follows, with a bitmask which is also a
    819 decimal number\&.
    820 .IP 
    821 This is probably best explained by a few examples:
    822 .IP 
    823 .IP o 
    824 \f(CWallowfrom 10/8;\fP will allow connections from
    825 \f(CW10\&.*\&.*\&.*\fP (a full Class A network)\&. The mask \f(CW/8\fP means
    826 that the first 8 bits of the number (ie\&., only the \f(CW10\fP) are
    827 significant\&. On the last 3 positions of the IP address, all
    828 numbers are allowed\&. Given this directive, client connections
    829 from e\&.g\&. 10\&.1\&.1\&.1 and 10\&.2\&.3\&.4 will be allowed\&.
    830 .IP 
    831 .IP o 
    832 \f(CWallowfrom 10\&.3/16;\fP will allow all IP addresses that
    833 start with \f(CW10\&.3\fP\&.
    834 .IP 
    835 .IP o 
    836 \f(CWallowfrom 10\&.3\&.1/16;\fP is the same as above\&. The third
    837 byte of the IP address is superfluous because the netmask
    838 specifies that only the first 16 bits (2 numbers) are taken
    839 into account\&.
    840 .IP 
    841 .IP o 
    842 \f(CWallowfrom 10\&.3\&.1\&.15;\fP allows traffic from only the
    843 specified IP address\&. There is no bitmask; all four numbers
    844 are relevant\&.
    845 .IP 
    846 .IP o 
    847 \f(CWallowfrom 10\&.3\&.1\&.15 10\&.2/16;\fP allows traffic from one
    848 IP address \f(CW10\&.3\&.1\&.15\fP or from a complete Class B network
    849 \f(CW10\&.2\&.*\&.*\fP 
    850 .IP 
    851 .IP o 
    852 \f(CWallowfile /tmp/myfile\&.txt;\fP in combination with a file
    853 \f(CW/tmp/myfile\&.txt\fP, with the contents \f(CW10\&.3\&.1\&.15 10\&.2/16\fP,
    854 is the same as above\&.
    855 .IP "Syntax:"
    856 .IP o 
    857 \f(CWallowfrom\fP \fIfilter-specificication(s)\fP
    858 .IP o 
    859 \f(CWdenyfrom\fP  \fIfilter-specificication(s)\fP
    860 .IP o 
    861 \f(CWallowfile\fP  \fIfilename\fP
    862 .IP o 
    863 \f(CWdenyfile\fP  \fIfilename\fP
    864 .IP "Default:"
    865 In absence of these statements, all client IP\&'s are accepted\&.
    866 
    867 .PP 
    868 
    869 .SH "4\&.2\&.11: useraccount - Limiting the effective ID of external processes"
    870 .IP "Description:"
    871 Using the directive \f(CWuseraccount\fP, the effective user and group
    872 ID can be restricted\&. This comes into effect when Crossroads runs
    873 external commands, such as:
    874 .IP o 
    875 Hooks for \f(CWonstart\fP, \f(CWonend\fP or \f(CWonfail\fP;
    876 .IP o 
    877 External dispatchers, when \f(CWdispatchmode
    878 externalhandler\fP is in effect\&.
    879 Once a user name for external commands is specified, Crossroads
    880 assumes the associated user ID and group ID before running those
    881 commands\&.
    882 .IP "Syntax:"
    883 \f(CWuseraccount\fP \fIusername\fP
    884 .IP "Default:"
    885 None; when unspecified, external commands are run with the 
    886 ID that was in effect when Crossroads was started\&.
    887 
    888 .PP 
    889 
    890 .SH "4\&.3: Backend definitions"
    891 
    892 .PP 
    893 Inside the service definitions as are described in the previous
    894 section, \fIbackend definitions\fP must also occur\&. Backend definitions
    895 are started by the keyword \f(CWbackend\fP, followed by an identifier
    896 (the back end name) , and statements inside \f(CW{\fP and \f(CW}\fP:
    897 .PP 
    898 .nf 
    899 service myservice {
    900     \&.\&.\&.
    901     \&.\&.\&. // statements that define the
    902     \&.\&.\&. // service named \&'myservice\&'
    903     \&.\&.\&.
    904 
    905     backend mybackend {
    906         \&.\&.\&.
    907         \&.\&.\&. // statements that define the
    908         \&.\&.\&. // backend named \&'mybackend\&'
    909         \&.\&.\&.
    910     }
    911 }
    912 .fi 
    913 
    914 .PP 
    915 Each service definition must have at least one backend
    916 definition\&. There may be more (and probably will, if you want
    917 balancing and fail over) as long as the backend names differ\&.
    918 The statements in the backend definition blocks are described in the
    919 following sections\&.
    920 .PP 
    921 Some directives (\f(CWstickycookie\fP etc\&.) only have effect when
    922 Crossroads treats the network traffic as a stream of HTTP messages;
    923 i\&.e\&., when the service is declared with \f(CWtype http\fP\&. Incase of
    924 \f(CWtype any\fP, the HTTP-specific directives have no effect\&.
    925 .PP 
    926 
    927 .SH "4\&.3\&.1: server - Specifying the back end address"
    928 .IP "Description:"
    929 Each back end must be identified by the network name
    930 (server name) where it is located\&. For example: \f(CWserver
    931 10\&.1\&.1\&.23\fP, or \f(CWserver web\&.mydomain\&.org\fP\&. A TCP port specifier
    932 can follow the server name, as in \f(CWserver web\&.mydomain\&.org:80\fP\&.
    933 .IP "Syntax:"
    934 .IP o 
    935 \f(CWserver\fP \fIservername\fP, where \fIservername\fP is a
    936 network name or IP address;
    937 .IP o 
    938 \f(CWserver\fP \fIservername:port\fP
    939 .IP "Default:"
    940 There is no default\&. This is a required setting\&.
    941 
    942 .PP 
    943 
    944 .SH "4\&.3\&.2: verbosity - Controlling verbosity at the back end level"
    945 .IP "Description:"
    946 Similar to \f(CWservice\fP specifications, a
    947 \f(CWbackend\fP can have its own verbosity (\f(CWon\fP or \f(CWoff\fP)\&. When
    948 \f(CWon\fP, traffic to and fro this back end is reported\&.
    949 .IP "Syntax:"
    950 .IP o 
    951 \f(CWverbosity\fP \fIsetting\fP, or
    952 .IP o 
    953 \f(CWverbose\fP \fIsetting\fP, where \fIsetting\fP is \f(CWtrue\fP,
    954 \f(CWyes\fP or \f(CWon\fP, or \f(CWfalse\fP, \f(CWno\fP, \f(CWoff\fP to turn it
    955 off\&.
    956 .IP "Default:"
    957 \f(CWoff\fP
    958 
    959 .PP 
    960 
    961 .SH "4\&.3\&.3: weight - When a back end is more equal than others"
    962 .IP "Description:"
    963 To influence how backends are selected, a backend can specify its
    964 \&'weight\&' in the process\&. The higher the weight, the less likely a
    965 back end will be chosen\&. The default is 1\&.
    966 .IP 
    967 The weighing mechanism only applies to the dispatch modes
    968 \f(CWrandom\fP, \f(CWbyconnections\fP, \f(CWbysize\fP and \f(CWbyduration\fP\&. 
    969 The weight is in fact a penalty factor\&. E\&.g\&., if backend A has
    970 \f(CWweight 2\fP and backend B has \f(CWweight 1\fP, then backend B will
    971 be selected all the time, until its usage parameter is twice as
    972 large as the parameter of A\&. Think of it as a \&'sluggishness\&'
    973 statement\&.
    974 .IP "Syntax:"
    975 \f(CWweight\fP \fInumber\fP; the higher the number, the more \&'sluggish\&'
    976 a back end is
    977 .IP "Default:"
    978 1; all back ends have equal weight\&.
    979 
    980 .PP 
    981 
    982 .SH "4\&.3\&.4: decay - Levelling out activity of a back end"
    983 .IP "Description:"
    984 To make sure that a \&'spike\&' of activity doesn\&'t
    985 influence the perceived load of a back end forever, you may
    986 specify a certain decay\&. E\&.g, the statement \f(CWdecay 10\fP makes
    987 sure that the load that crossroads computes for this back end (be
    988 it in seconds or in bytes) is decreased by 10% each time that
    989 \fBan other\fP back end is hit\&. Decays are not applied to the count
    990 of concurrent connections\&.
    991 .IP 
    992 This means that when a given back end is hit, then its usage data
    993 of the transferred bytes and the connection duration are updated
    994 using the actual number of bytes and actual duration\&. However,
    995 when a different back end is hit, then the usage data are
    996 decreased by the specified decay\&. 
    997 .IP "Syntax:"
    998 \f(CWdecay\fP \fInumber\fP, where \fInumber\fP is a percentage that
    999 decreases the back end usage data when other back ends are
   1000 hit\&.
   1001 .IP "Default:"
   1002 0, meaning that no decay is applied to usage statistics\&.
   1003 
   1004 .PP 
   1005 
   1006 .SH "4\&.3\&.5: onstart, onend, onfail - Action Hooks"
   1007 .IP "Description:"
   1008 The three directives \f(CWonstart\fP, \f(CWonend\fP and \f(CWonfail\fP can be
   1009 specified to start system commands (external programs) when a
   1010 connection to a back end starts, fails or ends:
   1011 .IP o 
   1012 \f(CWonstart\fP commands will be run when Crossroads
   1013 successfully connects to a back end, and starts servicing;
   1014 .IP o 
   1015 \f(CWonend\fP commands will be run when a (previously
   1016 established) connection stops;
   1017 .IP o 
   1018 \f(CWonfail\fP commands will be run when Crossroads tries to
   1019 contact a back end to serve a client, but the back end can\&'t
   1020 be reached\&.
   1021 .IP 
   1022 The format is always \f(CWon\fP\fItype\fP \fIcommand\fP\&. The \fIcommand\fP
   1023 is an external program, optionally followed by arguments\&. The
   1024 command is expanded according to the following table:
   1025 .IP 
   1026 .IP o 
   1027 \f(CW%a\fP is the availability of the current back end, when
   1028 a current back end is established;
   1029 .IP o 
   1030 \f(CW%1a\fP is the availability of the first back end (0 when
   1031 unavailable, 1 if available); \f(CW%2a\fP is the availability of
   1032 the second back end, and so on;
   1033 .IP o 
   1034 \f(CW%b\fP is the name of the current back end, when one is
   1035 established; 
   1036 .IP o 
   1037 \f(CW%1b\fP is the name of the first back end, \f(CW%2b\fP of the
   1038 second back end, and so on;
   1039 .IP o 
   1040 \f(CW%e\fP is the count of seconds since start of epoch
   1041 (January 1st 1970 GMT);
   1042 .IP o 
   1043 \f(CW%r\fP is the IP address of the client that requests a
   1044 connection and for whom the external dispatcher should compute
   1045 a back end;
   1046 .IP o 
   1047 \f(CW%s\fP is the name of the current service that the client
   1048 connected to;
   1049 .IP o 
   1050 \f(CW%t\fP is the current local time in ASCII format, in
   1051 \fIYYYY-MM-DD/hhh:mm:ss\fP; 
   1052 .IP o 
   1053 \f(CW%T\fP is the current GMT time in ASCIII format;
   1054 .IP o 
   1055 \f(CW%v\fP is the Crossroads version;
   1056 .IP o 
   1057 Any other chararacter following a \f(CW%\fP sign is taken
   1058 literally; e\&.g\&. \f(CW%z\fP is just a z\&.
   1059 .IP 
   1060 .IP "Syntax:"
   1061 .IP o 
   1062 \f(CWonstart\fP \fIcommandline\fP
   1063 .IP o 
   1064 \f(CWonend\fP \fIcommandline\fP
   1065 .IP o 
   1066 \f(CWonfail\fP \fIcommandline\fP
   1067 .IP o 
   1068 \f(CWonsuccess\fP \fIcommandline\fP
   1069 .IP "Default:"
   1070 There is no default\&. Normally no external programs are run upon
   1071 connection, success or failure of a back end\&.
   1072 
   1073 .PP 
   1074 
   1075 .SH "4\&.3\&.6: trafficlog and throughputlog - Debugging and Performance Aids"
   1076 .IP "Description:"
   1077 Two directives are available
   1078 to log network traffic to files\&. They are \f(CWtrafficlog\fP and
   1079 \f(CWthroughputlog\fP\&.
   1080 .IP 
   1081 The \f(CWtrafficlog\fP statement causes all traffic to be logged in
   1082 hexadecimal format\&. Each line is prefixed by \f(CWB\fP or \f(CWC\fP,
   1083 depending on whether the information was received from the back
   1084 end or from the client\&.
   1085 .IP 
   1086 The \f(CWthroughputlog\fP statement writes shorthand transmissions to
   1087 its log, accompanied by timings\&.
   1088 .IP "Syntax:"
   1089 .IP o 
   1090 \f(CWtrafficlog\fP \fIfilename\fP
   1091 .IP o 
   1092 \f(CWthroughputlog\fP \fIfilename\fP
   1093 .IP "Default:"
   1094 none
   1095 
   1096 .PP 
   1097 
   1098 .SH "4\&.3\&.7: stickycookie - Back end selection with an HTTP cookie"
   1099 .IP "Description:"
   1100 The directive \f(CWstickycookie\fP \fIvalue\fP
   1101 causes Crossroads to unpack clients\&' requests, to check for
   1102 \fIvalue\fP in the cookies\&. When found, the message is routed to the
   1103 back end having the appropriate \f(CWstickycookie\fP directive\&.
   1104 .IP 
   1105 E\&.g\&., consider the following configuration:
   1106 .IP 
   1107 .nf 
   1108 service \&.\&.\&. {
   1109     \&.\&.\&.
   1110     backend one {
   1111         \&.\&.\&.
   1112         stickycookie "BalancerID=first";
   1113     }
   1114     backend two {
   1115         \&.\&.\&.
   1116         stickycookie "BalancerID=second";
   1117     }
   1118 }
   1119 .fi 
   1120 
   1121 .IP 
   1122 When clients\&' messages contain cookies named \f(CWBalancerID\fP with
   1123 the value \f(CWfirst\fP, then such messages are routed to backend
   1124 \f(CWone\fP\&. When the value is \f(CWsecond\fP then they are routed to the
   1125 backend \f(CWtwo\fP\&.
   1126 .IP 
   1127 There are basically to provide such cookies to a browser\&. First, a
   1128 back end can insert such a cookie into the HTTP response\&. E\&.g\&.,
   1129 the webserver of back end \f(CWone\fP might insert a cookie named
   1130 \f(CWBalancerID\fP, having value \f(CWfirst\fP\&.
   1131 Second, Crossroads can insert such cookies using a carefully
   1132 crafted directive \f(CWaddclientheader\fP\&.
   1133 .IP "Syntax:"
   1134 \f(CWstickycookie\fP \fIcookievalue\fP
   1135 .IP "Default:"
   1136 There is no default\&.
   1137 
   1138 .PP 
   1139 
   1140 .SH "4\&.3\&.8: HTTP Header Modification Directives"
   1141 .IP "Description:"
   1142 Crossroads understands the following
   1143 header modification directives: \f(CWaddclientheader\fP,
   1144 \f(CWappendclientheader\fP, \f(CWsetclientheader\fP, \f(CWaddserverheader\fP,
   1145 \f(CWappendserverheader\fP, \f(CWsetserverheader\fP\&.
   1146 .IP 
   1147 The directive names always consist of
   1148 \fIAction\fP\fIDestination\fP\f(CWheader\fP, where:
   1149 .IP 
   1150 .IP o 
   1151 The action is \f(CWadd\fP, \f(CWappend\fP or \f(CWinsert\fP\&.
   1152 .IP 
   1153 .IP o 
   1154 Action \f(CWadd\fP adds a header, even when headers with
   1155 the same name already are present in an HTTP
   1156 message\&. Adding headers is useful for e\&.g\&. \f(CWSet-Cookie\fP
   1157 headers; a message may contain several of such headers\&.
   1158 .IP 
   1159 .IP o 
   1160 Action \f(CWappend\fP adds a header if it isn\&'t present
   1161 yet in an HTTP message\&. If such a header is already
   1162 present, then the value is appended to the pre-existing
   1163 header\&. This is useful for e\&.g\&. \f(CWVia\fP headers\&. Imagine
   1164 an HTTP message with a header \f(CWVia: someproxy\fP\&. Then the
   1165 directive \f(CWappendclientheader "Via: crossroads"\fP will
   1166 rewrite the header to \f(CWVia: someproxy; crossroads\fP\&.
   1167 .IP 
   1168 .IP o 
   1169 Action \f(CWset\fP overwrites headers with the same
   1170 name; or adds a new header if no pre-existing is found\&.
   1171 This is useful for e\&.g\&. \f(CWHost\fP headers\&.
   1172 .IP 
   1173 .IP o 
   1174 The destination is one of \f(CWclient\fP or \f(CWserver\fP\&. When
   1175 the destination is \f(CWserver\fP, then Crossroads will apply such
   1176 directives to HTTP messages that originate from the browser
   1177 and are being forwarded to back ends\&. When the destination is
   1178 \f(CWclient\fP, then Crossroads will apply such directives to
   1179 backend responses that are shuttled to the browser\&.
   1180 .IP 
   1181 The format of the directives is e\&.g\&. \f(CWaddclientheader
   1182 "X-Processed-By: Crossroads"\fP\&. The directives expect one
   1183 argument; a string, consisting of a header name, a colon, and a
   1184 header value\&. As usual, the directive must end with a semicolon\&.
   1185 .IP 
   1186 The header value may contain one of the following formatting
   1187 directives:
   1188 .IP 
   1189 .IP o 
   1190 \f(CW%a\fP is the availability of the current back end, when
   1191 a current back end is established;
   1192 .IP o 
   1193 \f(CW%1a\fP is the availability of the first back end (0 when
   1194 unavailable, 1 if available); \f(CW%2a\fP is the availability of
   1195 the second back end, and so on;
   1196 .IP o 
   1197 \f(CW%b\fP is the name of the current back end, when one is
   1198 established; 
   1199 .IP o 
   1200 \f(CW%1b\fP is the name of the first back end, \f(CW%2b\fP of the
   1201 second back end, and so on;
   1202 .IP o 
   1203 \f(CW%e\fP is the count of seconds since start of epoch
   1204 (January 1st 1970 GMT);
   1205 .IP o 
   1206 \f(CW%r\fP is the IP address of the client that requests a
   1207 connection and for whom the external dispatcher should compute
   1208 a back end;
   1209 .IP o 
   1210 \f(CW%s\fP is the name of the current service that the client
   1211 connected to;
   1212 .IP o 
   1213 \f(CW%t\fP is the current local time in ASCII format, in
   1214 \fIYYYY-MM-DD/hhh:mm:ss\fP; 
   1215 .IP o 
   1216 \f(CW%T\fP is the current GMT time in ASCIII format;
   1217 .IP o 
   1218 \f(CW%v\fP is the Crossroads version;
   1219 .IP o 
   1220 Any other chararacter following a \f(CW%\fP sign is taken
   1221 literally; e\&.g\&. \f(CW%z\fP is just a z\&.
   1222 .IP 
   1223 The following examples show common uses of header modifications\&.
   1224 .IP 
   1225 .IP "Enforcing session stickiness:"
   1226 By combining
   1227 \f(CWstickycookie\fP and \f(CWaddclientheader\fP, HTTP session
   1228 stickiness is enforced\&. Consider the following configuration:
   1229 .IP 
   1230 .nf 
   1231 service \&.\&.\&. {
   1232     \&.\&.\&.
   1233     backend one {
   1234         \&.\&.\&.
   1235         addclientheader "Set-Cookie: BalancerID=first; path=/";
   1236         stickycookie "BalancerID=first";
   1237     }
   1238     backend two {
   1239         \&.\&.\&.
   1240         addclientheader "Set-Cookie: BalancerID=second; path=/";
   1241         stickycookie "BalancerID=second";
   1242     }
   1243 }
   1244 .fi 
   1245 
   1246 .IP 
   1247 The first request of an HTTP session is balanced to either
   1248 backend \f(CWone\fP or \f(CWtwo\fP\&. The server response is enriched
   1249 using \f(CWaddclientheader\fP with an appropriate cookie\&. A
   1250 subsequent request from the same browser now has that cookie
   1251 in place; and is therefore sent to the same back end where the
   1252 its predecessors went\&.
   1253 .IP 
   1254 .IP "Hiding the server software version:"
   1255 Many servers
   1256 (e\&.g\&. Apache) advertize their version, as in \f(CWServer: Apache
   1257 1\&.27\fP\&. This potentially provides information to attackers\&. The
   1258 following configuration hides such information:
   1259 .IP 
   1260 .nf 
   1261 service \&.\&.\&. {
   1262     \&.\&.\&.
   1263     backend one {
   1264         \&.\&.\&.
   1265         setclientheader "Server: WWW-Server";
   1266     }
   1267 }
   1268 .fi 
   1269 
   1270 .IP 
   1271 .IP "Informing the server of the clients\&' IP address:"
   1272 Since
   1273 Crossroads sits \&'in the middle\&' between a client and a back
   1274 end, the back end perceives Crossroads as its client\&. The
   1275 following sends the true clients\&' IP address to the server, in
   1276 a header \f(CWX-Real-IP\fP:
   1277 .IP 
   1278 .nf 
   1279 service \&.\&.\&. {
   1280     \&.\&.\&.
   1281     backend one {
   1282         \&.\&.\&.
   1283         setserverheader "X-Real-IP: %r";
   1284     }
   1285 }
   1286 .fi 
   1287 
   1288 .IP 
   1289 .IP "Keep-Alive Downgrading:"
   1290 The directives
   1291 \f(CWsetclientheader\fP and \f(CWsetserverheader\fP also play a key
   1292 role in downgrading Keep-Alive connections to
   1293 \&'single-shot\&'\&. E\&.g\&., the following configuration makes sure
   1294 that no Keep-Alive connections occur\&.
   1295 .IP 
   1296 .nf 
   1297 service \&.\&.\&. {
   1298     \&.\&.\&.
   1299     backend one {
   1300         \&.\&.\&.
   1301         setserverheader "Connection: close";
   1302         setclientheader "Connection: close";
   1303     }
   1304 }
   1305 .fi 
   1306 .IP "Syntax:"
   1307 .IP o 
   1308 \f(CWaddclientheader\fP \fIHeadername: headervalue\fP to add a
   1309 header in the traffic towards the client, even when another
   1310 header \fIHeadername\fP exists;
   1311 .IP o 
   1312 \f(CWappendclientheader\fP \fIHeadername: headervalue\fP to
   1313 append \fIheadervalue\fP to an existing header \fIHeadername\fP
   1314 in the traffic towards the client,
   1315 or to add the whole header alltogether;
   1316 .IP o 
   1317 \f(CWsetclientheader\fP \fIHeadername: headervalue\fP to
   1318 overwrite an existing header in the traffic towards the
   1319 client, or to add such a header;
   1320 .IP o 
   1321 \f(CWaddserverheader\fP \fIHeadername: headervalue\fP to add a
   1322 header in the traffic towards the server, even when another
   1323 header \fIHeadername\fP exists;
   1324 .IP o 
   1325 \f(CWappendserverheader\fP \fIHeadername: headervalue\fP to
   1326 append \fIheadervalue\fP to an existing header \fIHeadername\fP
   1327 in the traffic towards the server,
   1328 or to add the whole header alltogether;
   1329 .IP o 
   1330 \f(CWsetserverheader\fP \fIHeadername: headervalue\fP to
   1331 overwrite an existing header in the traffic towards the
   1332 server, or to add such a header\&.
   1333 .IP "Default:"
   1334 There is no default\&.
   1335 
   1336 .PP 
   1337 
   1338 .SH "5: Tips, Tricks and Remarks"
   1339 
   1340 The following sections elaborate on the directives as described in
   1341 section ?? to illustrate how crossroads works and to help you
   1342 achieve the "optimal" balancing configuration\&.
   1343 .PP 
   1344 
   1345 .SH "5\&.1: How back ends are selected in load balancing"
   1346 
   1347 .PP 
   1348 In order to tune your load balancing, you\&'ll need to understand how
   1349 crossroads computes usage, how weighing works, and so on\&. In this
   1350 section we\&'ll focus on the dispatching modes \f(CWbysize\fP, \f(CWbyduration\fP
   1351 and \f(CWbyconnections\fP only\&. The other dispatching types are
   1352 self-explanatory\&. 
   1353 .PP 
   1354 
   1355 .SH "5\&.1\&.1: Bysize, byduration or byconnections?"
   1356 
   1357 .PP 
   1358 As stated before, crossroads doesn\&'t know \&'what a service does\&' and
   1359 how to judge whether a given back end is very busy or not\&. You
   1360 must therefore give the right hints:
   1361 .PP 
   1362 .IP o 
   1363 In general, a service which is CPU bound, will be more
   1364 busy when it takes longer to process a request\&. The dispatch
   1365 mode \f(CWbyduration\fP is appropriate here\&.
   1366 .IP 
   1367 .IP o 
   1368 In contrast, a service which is filesystem bound, will be
   1369 more busy when more data are transferred\&. The dispatch mode
   1370 \f(CWbysize\fP is apppropriate\&.
   1371 .IP 
   1372 .IP o 
   1373 The dispatch mode \f(CWbyduration\fP can also be used when
   1374 network latency is an issue\&. E\&.g\&., if your balancer has back
   1375 ends that are geograpically distributed, then \f(CWbyduration\fP
   1376 would be a good way to select best available back ends\&.
   1377 .IP 
   1378 .IP o 
   1379 Furthermore it is noteworthy that \f(CWdispatchmode
   1380 byduration\fP is not usable for interactive processes such as
   1381 SSH logins\&. Idle time of a
   1382 login adds to the duration, while causing (almost) no
   1383 load\&. Mode \f(CWbyduration\fP should only be used for automated
   1384 processes that don\&'t wait for user interaction (e\&.g\&., SOAP
   1385 calls and other HTTP requests)\&.
   1386 .IP 
   1387 .IP o 
   1388 As a last remark, the dispatching mode \f(CWbyconnections\fP can
   1389 be used if you don\&'t have other clues for load
   1390 estimations\&.
   1391 .IP 
   1392 E\&.g\&., consider a database connection\&. What\&'s
   1393 heavier on the back end, time-consuming connections, or connections
   1394 where loads of bytes are transferred? Well, that depends\&. A
   1395 tough \f(CWselect\fP query that joins multiple tables can be very
   1396 heavy on the back end, though the response set can be quite
   1397 small - and hence the number of
   1398 transferred bytes\&. That would suggest
   1399 dispatching by duration\&. However, \f(CWbyduration\fP
   1400 balancing doesn\&'t respresent the true world, when interactive
   1401 connections can occur where users have an idle TCP connection to
   1402 the database:
   1403 this consumes time, but no bytes (see the SSH login example
   1404 above)\&. In this case, the dispatch mode \f(CWbyconnections\fP may be
   1405 your best bet\&.
   1406 .IP 
   1407  
   1408 .SH "5\&.1\&.2: Averaging size and duration"
   1409 
   1410 .PP 
   1411 The configuration statement \f(CWdispatchmode bysize\fP or \f(CWbyduration\fP
   1412 allows an optional modifier \f(CWover\fP \fInumber\fP, where the stated
   1413 number represents a connection count\&. When this modifier is present, then
   1414 crossroads will use a moving average over the last \fIn\fP connections to
   1415 compute duration and size figures\&.
   1416 .PP 
   1417 In the real world you\&'ll always want this modifier\&. E\&.g\&., consider two
   1418 back ends that are running for years now, and one of them is suddenly
   1419 overloaded and very busy (it experiences a \&'spike\&' in activity)\&.
   1420 When the \f(CWover\fP modifier is absent, then
   1421 the sudden load will hardly show up in the usage figures -- it will
   1422 flatten out due to the large usage figures already stored in the years
   1423 of service\&.
   1424 .PP 
   1425 In contrast, when e\&.g\&. \f(CWover 3\fP is in effect, then a sudden load
   1426 does show up -- because it highly contributes to the average of three
   1427 connections\&.
   1428 .PP 
   1429 
   1430 .SH "5\&.1\&.3: Specifying decays"
   1431 
   1432 .PP 
   1433 Decays are also only relevant when crossroads computes the \&'next best
   1434 back end\&' by size (bytes) or duration (seconds)\&. E\&.g\&., imagine two
   1435 back ends A and B, both averaged over say 3 connections\&.
   1436 .PP 
   1437 Now when back end A is suddenly hit by a spike,
   1438 its average would go up accordingly\&. But the back end would never
   1439 again be used, unless B also received a similar spike, because A\&'s
   1440 \&'usage data\&' over its last three connections would forever be larger than
   1441 B\&'s data\&. 
   1442 .PP 
   1443 For that reason, you should in real situations probably always
   1444 specify a decay, so that the backend selection algorithm recovers from
   1445 spikes\&. Note that the usage data of the back end where a decay is
   1446 specified, decay when \fBother\fP back ends are hit\&. The decay parameter
   1447 is like specifying how fast your body regenerates when someone else
   1448 does the work\&.
   1449 .PP 
   1450 The below configuration illustrates this:
   1451 .PP 
   1452 .nf 
   1453 /* Definition of the service */
   1454 service soap {
   1455     /* Local TCP port */
   1456     port 8080;
   1457 
   1458     /* We\&'ll select back ends by the processing
   1459      * duration
   1460      */
   1461     dispatchmode byduration over 3;
   1462 
   1463     /* First back end: */
   1464     backend A {
   1465         /* Back end IP address and port */
   1466         server 10\&.1\&.1\&.1:8080;
   1467 
   1468         /* When this back end is NOT hit because
   1469          * the other one was less busy, then the
   1470          * usage parameters decay 10% per connection
   1471          */
   1472         decay 10;
   1473     }
   1474 
   1475     /* Second back end: */
   1476     backend B {
   1477         server 10\&.1\&.1\&.2:8080;
   1478         decay 10;
   1479     }
   1480 }
   1481 .fi 
   1482 
   1483 .PP 
   1484 
   1485 .SH "5\&.1\&.4: Adjusting the weights"
   1486 
   1487 .PP 
   1488 The back end modifier \f(CWweight\fP is useful in situations where your
   1489 back ends differ in respect to performance\&. E\&.g,\&. your back ends may
   1490 be geographically distributed, and you know that a given back end is
   1491 difficult to reach and often experiences network lag\&.
   1492 .PP 
   1493 Or you may have
   1494 one primary back end, a system with a fast CPU and enough memory, and a
   1495 small fall-back back end, with a slow CPU and short on memory\&. In that
   1496 case you know in advance that the second back end should be used only
   1497 rarely\&. Most requests should go to the big server, up to a certain load\&.
   1498 .PP 
   1499 In such cases you will know in advance that the best performing back ends
   1500 should be selected the most often\&. Here\&'s where the \f(CWweight\fP
   1501 statement comes in: you can simply increase the weight of the back
   1502 ends with the least performance, so that they are selected less
   1503 frequently\&.
   1504 .PP 
   1505 E\&.g\&., consider the following configuration:
   1506 .PP 
   1507 .nf 
   1508 service soap {
   1509     port 8080;
   1510     dispatchmode byduration over 3;
   1511     backend A {
   1512         server 10\&.1\&.1\&.1:8080;
   1513         decay 20;
   1514     }
   1515     backend B {
   1516         server 10\&.1\&.1\&.2:8080;
   1517         weight 2;
   1518         decay 10;
   1519     }
   1520     backend C {
   1521         server 10\&.1\&.1\&.3:8080;
   1522         weight 4;
   1523         decay 5;
   1524     }
   1525 }
   1526 .fi 
   1527 
   1528 .PP 
   1529 This will cause crossroads to select back ends by the processing time,
   1530 averaging over the last three connections\&. However, backend B will kick
   1531 in only when its usage is half of the usage of A (back end B is
   1532 probably only half as fast as A)\&. Backend C will kick in only when its
   1533 usage is a quarter of the usage of A, which is half of the usage of B
   1534 (back end C is probably very weak, and just a fall-back system incase
   1535 both A and B crash)\&. Note also that A\&'s usage data decay much faster
   1536 than B\&'s and C\&'s: we\&'re assuming that this big server recovers quicker
   1537 than its smaller siblings\&.
   1538 .PP 
   1539 
   1540 .SH "5\&.1\&.5: Throttling the number of concurrent connections"
   1541 
   1542 .PP 
   1543 If you suspect that your service may occasionally receive \&'spikes\&' of
   1544 activity\e (which you should always assume), then it might be a
   1545 good idea to protect your service by specifying a maximum number of
   1546 concurrent connections\&. This protection can be specified on two levels:
   1547 .PP 
   1548 .IP "On the service level"
   1549 a statement like \f(CWmaxconnections
   1550 100;\fP states that the service as a whole will never
   1551 service more than 100 concurrent connections\&. This means that
   1552 all your back ends and the crossroads balancer itself
   1553 will be protected from being overloaded\&.
   1554 .IP "On the back end level"
   1555 a statement like \f(CWmaxconnections 10;\fP
   1556 states that this particular back end will never have more
   1557 than 10 concurrent connections; regardless of the overall
   1558 setting on the service level\&. This means that this
   1559 particular back end will be protected from being
   1560 overloaded (regardless of what other back ends may
   1561 experience)\&.
   1562 .PP 
   1563 The \f(CWmaxconnections\fP statement, combined with a back end selection
   1564 algorithm, allows very fine granularity\&. The \f(CWmaxconnections\fP statement
   1565 on the back end level is like a hand brake: even when you specify a
   1566 back end algorithm that would protect a given back end from being used
   1567 too much, a situation may occur where that back end is about to be
   1568 hit\&. A \f(CWmaxconnections\fP statement on the level of that back may then
   1569 protect it\&.
   1570 .PP 
   1571 
   1572 .SH "5\&.2: Using an external program to dispatch"
   1573 
   1574 .PP 
   1575 As mentioned before, Crossroads supports several built-in dispatch
   1576 modes\&. However, you are always free to hook-in your own dispatch mode
   1577 that determines the next back end using your own specific
   1578 algorithm\&. This section explains how to do it\&.
   1579 .PP 
   1580 
   1581 .SH "5\&.2\&.1: Configuring the external handler"
   1582 
   1583 .PP 
   1584 First, the \f(CWdispatchmode\fP statement needs to inform Crossroads that
   1585 an external program will do the job\&. The syntax is: \f(CWdispatchmode
   1586 externalhandler\fP \fIprogram arguments\fP\&. The \fIprogram\fP must point to
   1587 an executable program that will be started by Crossroads\&. The
   1588 specifier \fIarguments\fP can be anything you want; those will be the
   1589 arguments to Crossroads\&. You can however use the following special
   1590 format specifiers:
   1591 .PP 
   1592 .IP o 
   1593 \f(CW%a\fP is the availability of the current back end, when
   1594 a current back end is established;
   1595 .IP o 
   1596 \f(CW%1a\fP is the availability of the first back end (0 when
   1597 unavailable, 1 if available); \f(CW%2a\fP is the availability of
   1598 the second back end, and so on;
   1599 .IP o 
   1600 \f(CW%b\fP is the name of the current back end, when one is
   1601 established; 
   1602 .IP o 
   1603 \f(CW%1b\fP is the name of the first back end, \f(CW%2b\fP of the
   1604 second back end, and so on;
   1605 .IP o 
   1606 \f(CW%e\fP is the count of seconds since start of epoch
   1607 (January 1st 1970 GMT);
   1608 .IP o 
   1609 \f(CW%r\fP is the IP address of the client that requests a
   1610 connection and for whom the external dispatcher should compute
   1611 a back end;
   1612 .IP o 
   1613 \f(CW%s\fP is the name of the current service that the client
   1614 connected to;
   1615 .IP o 
   1616 \f(CW%t\fP is the current local time in ASCII format, in
   1617 \fIYYYY-MM-DD/hhh:mm:ss\fP; 
   1618 .IP o 
   1619 \f(CW%T\fP is the current GMT time in ASCIII format;
   1620 .IP o 
   1621 \f(CW%v\fP is the Crossroads version;
   1622 .IP o 
   1623 Any other chararacter following a \f(CW%\fP sign is taken
   1624 literally; e\&.g\&. \f(CW%z\fP is just a z\&.
   1625 .PP 
   1626 Note that the format specifiers such as \f(CW%b\fP don\&'t make sense in the
   1627 phase in which an external handler is called, since there is no
   1628 current back end yet (the job of the handler is to supply one)\&.
   1629 .PP 
   1630 
   1631 .SH "5\&.2\&.2: Writing the external handler"
   1632 
   1633 .PP 
   1634 The external handler is activated using the arguments that are
   1635 specified in \f(CW/etc/crossroads\&.conf\fP\&. The external handler can do
   1636 whatever it wants, but ultimately, it must write a back end name on
   1637 its \fIstdout\fP\&. Crossroads reads this, and if the back end is
   1638 available, uses that back end for the connection\&.
   1639 .PP 
   1640 
   1641 .SH "5\&.2\&.3: Examples of external handlers"
   1642 
   1643 .PP 
   1644 This section shows some examples of Crossroads configurations
   1645 vs\&. external handlers\&. The sample handlers that are shown here, are
   1646 also included in the Crossroads distribution, under the directory
   1647 \f(CWetc/\fP\&. Also note that the examples shown here are just
   1648 quick-and-dirty Perl scripts, meant to illustrate only\&. Your
   1649 applications may need other external handlers, but you can use the
   1650 shown scripts as a starting point\&.
   1651 .PP 
   1652 .SH "Round-robin dispatching"
   1653 
   1654 .PP 
   1655 This example is trivial in the sense that round-robin dispatching is
   1656 already built into Crossroads, so
   1657 that using an external handler for this purpose only slows down
   1658 Crossroads\&. However, it\&'s a good starting example\&.
   1659 .PP 
   1660 The Crossroads configuration is shown below:
   1661 .PP 
   1662 .nf 
   1663 service test {
   1664     port 8001;
   1665     verbosity on;
   1666     revivinginterval 5;
   1667     
   1668     dispatchmode externalhandler
   1669         /usr/local/src/crossroads/etc/dispatcher-roundrobin
   1670             %1b %1a %2b %2a;
   1671 
   1672     backend testone {
   1673         server localhost:3128;
   1674         verbosity on;
   1675     }
   1676     backend testtwo {
   1677         server locallhost:3128;
   1678         verbosity on;
   1679     }
   1680 }
   1681 .fi 
   1682 
   1683 .PP 
   1684 The relevant \f(CWdispatchmode\fP statement invokes the external program
   1685 \f(CWdispatcher-roundrobin\fP with four arguments: the name of the first
   1686 back end (\f(CWtestone\fP), its availability (0 or 1), the name of the
   1687 second back end (\f(CWtesttwo\fP) and its availability (0 or 1)\&.
   1688 .PP 
   1689 The external handler, which is also included in the Crossroads
   1690 distribution, is shown below\&. It is a Perl script\&.
   1691 .PP 
   1692 .nf 
   1693 #!/usr/bin/perl
   1694 
   1695 use strict;
   1696 
   1697 # Example of a round-robin external dispatcher\&. This is totally
   1698 # superfluous, Crossroads has this on-board; if you use the external
   1699 # program for determining round-robin dispatching, then you\&'ll only
   1700 # slow things down\&. This script is just meant as an example\&.
   1701 
   1702 # Globals / configuration
   1703 # -----------------------
   1704 my $log = \&'/tmp/exthandler\&.log\&';    # Debug log, set to /dev/null to suppress
   1705 my $statefile = \&'/tmp/rr\&.last\&';	    # Where we keep the last used
   1706 
   1707 # Logging
   1708 # -------
   1709 sub msg {
   1710     return if ($log eq \&'/dev/null\&' or $log eq \&'\&');
   1711     open (my $of, ">>$log") or return;
   1712     print $of (scalar(localtime()), \&' \&', @_);
   1713 }
   1714 
   1715 # Read the last used back end
   1716 # ---------------------------
   1717 sub readlast() {
   1718     my $ret;
   1719     
   1720     if (open (my $if, $statefile)) {
   1721         $ret = <$if>;
   1722         chomp ($ret);
   1723         close ($if);
   1724         msg ("Last used back end: $ret\en");
   1725         return ($ret);
   1726     }
   1727     msg ("No last-used back end (yet)\en");
   1728     return (undef);    
   1729 }
   1730 
   1731 # Write back the last used back end, reply to Crossroads and stop
   1732 # ---------------------------------------------------------------
   1733 sub reply ($) {
   1734     my $last = shift;
   1735 
   1736     if (open (my $of, ">$statefile")) {
   1737         print $of ("$last\en");
   1738     }
   1739     print ("$last\en");
   1740     exit (0);
   1741 }
   1742 
   1743 # Main starts here
   1744 # ----------------
   1745 
   1746 # Collect the cmdline arguments\&. We expect pairs of backend-name /
   1747 # backend-availablility, and we\&'ll store only the available ones\&.
   1748 msg ("Dispatch request received\en");
   1749 my @backend;
   1750 for (my $i = 0; $i <= $#ARGV; $i += 2) {
   1751     push (@backend,  $ARGV[$i]) if ($ARGV[$i + 1]);
   1752 }
   1753 msg ("Available back ends: @backend\en");
   1754 
   1755 # Let\&'s see what the last one is\&. If none found, then we return the
   1756 # first available back end\&. Otherwise we need to go thru the list of
   1757 # back ends, and return the next one in line\&.
   1758 my $last = readlast();
   1759 if ($last eq \&'\&') {
   1760     msg ("Returning first available back end $backend[0]\en");
   1761     reply ($backend[0]);
   1762 }
   1763 
   1764 # There **was** a last back end\&.  Try to match it in the list,
   1765 # then return the next-in-line\&.
   1766 for (my $i = 0; $i < $#backend; $i++) {
   1767     if ($last eq $backend[$i]) {
   1768         msg ("Returning next back end ", $backend[$i + 1], "\en");
   1769         reply ($backend[$i + 1]);
   1770     }
   1771 }
   1772 
   1773 # No luck\&.\&. run back to the first one\&.
   1774 msg ("Returning first back end $backend[0]\en");
   1775 reply ($backend[0]);
   1776 .fi 
   1777 
   1778 .PP 
   1779 The working of the script is basically as follows:
   1780 .PP 
   1781 .IP o 
   1782 The argument list is scanned\&. Back ends that are
   1783 available are collected in an array \f(CW@backend\fP\&.
   1784 .IP 
   1785 .IP o 
   1786 The script queries a state file \f(CW/tmp/rr\&.last\fP\&. If a
   1787 back end name occurs there, then the next back end is looked
   1788 up in \f(CW@backend\fP and returned to Crossroads\&. If no last back
   1789 is unknown or can\&'t be matched, then the first available back
   1790 end (first element of \f(CW@backend\fP) is returned to Crossroads\&.
   1791 .IP 
   1792 .IP o 
   1793 Informing Crossroads is done via the subroutine
   1794 \f(CWreply()\fP\&. This code writes the selected back end to file
   1795 \f(CW/tmp/rr\&.last\fP (for future usage) and prints the back end
   1796 name to \fIstdout\fP\&.
   1797 .IP 
   1798 .IP o 
   1799 The script logs its actions to a file
   1800 \f(CW/tmp/exthandler\&.log\fP\&. This log file can be inspected for
   1801 the script\&'s actions\&.
   1802 .PP 
   1803 .SH "Dispatching by the client IP address"
   1804 
   1805 .PP 
   1806 The following example shows a useful real-life situation\&. The
   1807 situation is as follows:
   1808 .PP 
   1809 .IP o 
   1810 Crossroads is used as a single-address point to forward
   1811 Remote Desktop requests to a farm of Windows systems, where
   1812 users can work via remote access;
   1813 .IP 
   1814 .IP o 
   1815 However, users may stop their session, and when they
   1816 re-connect, they expect to be sent to the Windows system that
   1817 they had worked on previously;
   1818 .IP 
   1819 .IP o 
   1820 Client PC\&'s have their distinct IP addresses, which
   1821 distinguishes them\&.
   1822 .IP 
   1823 .IP o 
   1824 Of four windows systems, two are large servers, and two
   1825 are small ones\&. We\&'ll want to assign large servers to clients
   1826 when we have a choice\&.
   1827 .PP 
   1828 The requirements resemble session stickiness in HTTP, except that the remote
   1829 desktop protocol doesn\&'t support stickiness\&. This situation is a
   1830 perfect example of how an external handler can help:
   1831 .PP 
   1832 .IP o 
   1833 A suitable dispatch mode isn\&'t yet available in
   1834 Crossroads, but can be easily coded in an external handler;
   1835 .IP 
   1836 .IP o 
   1837 The potential delay due to the calling of an external
   1838 handler won\&'t even be noticed\&. This is a network service where
   1839 the connection time isn\&'t critical; we\&'d expect only a few
   1840 (albeit lengthy) TCP connections\&.
   1841 .PP 
   1842 The approach to the solution of this problem uses several external
   1843 program hooks:
   1844 .PP 
   1845 .IP o 
   1846 An external dispatcher handler will be responsible for
   1847 suggesting a back end, given a client IP and given the current
   1848 timestamp\&. This handler will consult an internal
   1849 administration to see whether the stated IP address should
   1850 re-use a back end, or to determine which back end is free for usage\&.
   1851 .IP o 
   1852 An external hook \f(CWonstart\fP will be responsible for
   1853 updating the internal administration; i\&.e\&., to flag a back end
   1854 as \&'occupied\&'\&.
   1855 .IP o 
   1856 The external hooks \f(CWonfailure\fP and \f(CWonend\fP will be
   1857 responsible for flagging a back end as \&'free\&' again; i\&.e\&., for
   1858 erasing any previous information that states that the back end
   1859 was occupied\&.
   1860 .PP 
   1861 The Crossroads configuration is shown below\&. Only four Windows back
   1862 ends are shown\&. Each back end is configured on a
   1863 given IP address, port 3389, and is limited to one concurrent connection
   1864 (otherwise a new user might \&'steal\&' a running desktop session)\&.
   1865 .PP 
   1866 .nf 
   1867 service rdp {
   1868     port 3389;
   1869     revivinginterval 5;
   1870 
   1871     /* rdp-helper dispatch IP STAMP \&.\&.\&.  will suggest a back end to use,
   1872      * arguments are for all back ends: name, availability, weight */
   1873     dispatchmode externalhandler
   1874         /usr/local/src/crossroads/etc/rdp-helper dispatch %r %e
   1875             %1b %1a %1w
   1876             %2b %2a %2w
   1877             %3b %3a %3w
   1878             %4b %4a %4w;
   1879             
   1880     backend win1 {
   1881         server 10\&.1\&.1\&.1:3389;
   1882         maxconnections 1;
   1883         /* rdp-helper start IP STAMP BACKEND will log the actual start
   1884          * of a connection;
   1885          * rdp-helper end IP will log the ending of a connection */
   1886         onstart /usr/local/src/crossroads/etc/rdp-helper start %r %e %b;
   1887         onend   /usr/local/src/crossroads/etc/rdp-helper end %r;
   1888         onfail  /usr/local/src/crossroads/etc/rdp-helper end %r;
   1889     }
   1890     backend win2 {
   1891         server 10\&.1\&.1\&.2:3389;
   1892         maxconnections 1;
   1893         onstart /usr/local/src/crossroads/etc/rdp-helper start %r %e %b;
   1894         onend   /usr/local/src/crossroads/etc/rdp-helper end %r;
   1895         onfail  /usr/local/src/crossroads/etc/rdp-helper end %r;
   1896     }
   1897     backend win3 {
   1898         server 10\&.1\&.1\&.3:3389;
   1899         maxconnections 1;
   1900         weight 2;
   1901         onstart /usr/local/src/crossroads/etc/rdp-helper start %r %e %b;
   1902         onend   /usr/local/src/crossroads/etc/rdp-helper end %r;
   1903         onfail  /usr/local/src/crossroads/etc/rdp-helper end %r;
   1904     }
   1905     backend win4 {
   1906         server 10\&.1\&.1\&.4:3389;
   1907         maxconnections 1;
   1908         weight 3;
   1909         onstart /usr/local/src/crossroads/etc/rdp-helper start %r %e %b;
   1910         onend   /usr/local/src/crossroads/etc/rdp-helper end %r;
   1911         onfail  /usr/local/src/crossroads/etc/rdp-helper end %r;
   1912     }
   1913 }
   1914 .fi 
   1915 
   1916 .PP 
   1917 Depending on the dispatcher stage, the exernal handler \f(CWrdp-helper\fP
   1918 is invoked in different ways:
   1919 .PP 
   1920 .IP "During dispatching"
   1921 the helper is called to suggest a back
   1922 end\&. The arguments are an action indicator \f(CWdispatch\fP, the
   1923 client\&'s IP address, the timestamp, and four triplets that
   1924 represent back ends: per back end its name, its availability,
   1925 and its weight\&. The purpose of the helper is to tell
   1926 Crossroads which back end to use\&.
   1927 .IP 
   1928 .IP "During connection start"
   1929 the helper will be invoked to
   1930 inform it of the start of a connection, given a client IP
   1931 address\&.
   1932 .IP 
   1933 .IP "When a connection terminates"
   1934 the helper will be invoked
   1935 to inform it that the connection has ended\&.
   1936 .PP 
   1937 Here\&'s the external handler as Perl script\&. It uses the module
   1938 \f(CWGDBM_File\fP which most likely will not be part of standard Perl
   1939 distributions, but can be added using CPAN\&. (Alternatively, any other
   1940 database module can be used\&.)
   1941 .PP 
   1942 .nf 
   1943 #!/usr/bin/perl
   1944 
   1945 use strict;
   1946 use GDBM_File;
   1947 
   1948 # Global variables and configuration
   1949 # ----------------------------------
   1950 my $log = \&'/tmp/exthandler\&.log\&';    # Debug log, set to /dev/null to suppress
   1951 my $cdb = \&'/tmp/client\&.db\&';         # GDBM database of clients
   1952 my %db;                             # \&.\&. and memory representation of it
   1953 my $timeout = 24*60*60;             # Timeout of a connection in secs
   1954 
   1955 # Logging
   1956 # -------
   1957 sub msg {
   1958     return if ($log eq \&'/dev/null\&' or $log eq \&'\&');
   1959     open (my $of, ">>$log") or return;
   1960     print $of (scalar(localtime()), \&' \&', @_);
   1961     close ($of);
   1962 }
   1963 
   1964 # Reply a back end to the caller and stop processing\&.
   1965 # ---------------------------------------------------
   1966 sub reply ($) {
   1967     my $b = shift;
   1968     msg ("Suggesting $b to Crossroads\&.\en");
   1969     print ("$b\en");
   1970     exit (0);
   1971 }
   1972 
   1973 # Is a value in an array
   1974 # ----------------------
   1975 sub inarray {
   1976     my $val = shift;
   1977     for my $other (@_) {
   1978         return (1) if ($other eq $val);
   1979     }
   1980     return (0);
   1981 }
   1982 
   1983 # A connection is starting
   1984 # ------------------------
   1985 sub start {
   1986     my ($ip, $stamp, $backend) = @_;
   1987     msg ("Logging START of connection for IP $ip on stamp $stamp, ",
   1988          "back end $backend\en");
   1989     $db{$ip} = "$backend:$stamp";
   1990 }
   1991 
   1992 # A connection has ended
   1993 # ----------------------
   1994 sub end {
   1995     my $ip = shift;
   1996     msg ("Logging END of connection for IP $ip\en");
   1997     $db{$ip} = undef;
   1998 }
   1999 
   2000 # Request to determine a back end
   2001 # -------------------------------
   2002 sub dispatch {
   2003     my $ip = shift;
   2004     my $stamp = shift;
   2005 
   2006     msg ("Request to dispatch IP $ip on stamp $stamp\en");
   2007     
   2008     # Read the next arguments\&. They are triplets of
   2009     # backend-name / availability / weight\&. Store if the back end is
   2010     # available\&.
   2011     my (@backends, @weights);
   2012     for (my $i = 0; $i < $#_; $i += 3) {
   2013         if ($_[$i + 1] != 0) {
   2014             push (@backends, $_[$i]);
   2015             push (@weights,  $_[$i + 2]);
   2016             msg ("Candidate back end: $_[$i] with weight ", $_[$i + 2], "\en");
   2017         }
   2018     }
   2019 
   2020     # See if this is a reconnect by a previously seen client IP\&. We\&'ll
   2021     # treat this as a reconnect if the timeout wasn\&'t yet exceeded\&.
   2022     if ($db{$ip} ne \&'\&') {
   2023         my ($last_backend, $last_stamp) = split (/:/, $db{$ip});
   2024         msg ("IP $ip had last connected on $last_stamp to $last_backend\en");
   2025         if ($stamp < $last_stamp + $timeout) {
   2026             msg ("Timeout not yet exceeded, this may be a reconnect\en");
   2027             # We\&'ll allow a reconnect only if the stated last_backend is
   2028             # free (sanity check)\&.
   2029             if (inarray ($last_backend, @backends)) {
   2030                 msg ("Last back end $last_backend is available, ",
   2031                      "letting through\en");
   2032                 reply ($last_backend);
   2033             } else {
   2034                 msg ("Last used back end isn\&'t free, suggesting a new one\en");
   2035             }
   2036         } else {
   2037             msg ("Timeout exceeded, suggesting a new back end\en");
   2038         }
   2039     } else {
   2040         msg ("Np preveious connection data, suggesting a new back end\en");
   2041     }
   2042 
   2043     my $bestweight = -1;
   2044     my $bestbackend;
   2045     for (my $i = 0; $i <= $#weights; $i++) {
   2046         if ($bestweight == -1 or $bestweight > $weights[$i]) {
   2047             $bestweight  = $weights[$i];
   2048             $bestbackend = $backends[$i];
   2049         }
   2050     }
   2051 
   2052     msg ("Best back end: $bestbackend (given weight $bestweight)\en");
   2053     reply ($bestbackend);
   2054 }
   2055 
   2056 # Main starts here
   2057 # ----------------
   2058 msg ("Start of run, attaching GDBM database \&'$cdb\&'\en");
   2059 tie (%db, \&'GDBM_File\&', $cdb, &GDBM_WRCREAT, 0600);
   2060 
   2061 # The first argument must be an action \&'dispatch\&', \&'start\&' or \&'end\&'\&.
   2062 # Depending on the action, we do stuff\&.
   2063 my $action = shift (@ARGV);
   2064 if ($action eq \&'dispatch\&') {
   2065     dispatch (@ARGV);
   2066 } elsif ($action eq \&'start\&') {
   2067     start (@ARGV);
   2068 } elsif ($action eq \&'end\&') {
   2069     end (@ARGV);
   2070 } else {
   2071     print STDERR ("Usage: rdp-helper {dispatch|start|end} args\en");
   2072     exit (1);
   2073 }
   2074 .fi 
   2075 
   2076 .PP 
   2077 
   2078 .SH "5\&.3: HTTP Session Stickiness"
   2079 
   2080 .PP 
   2081 This section focuses on HTTP session stickiness\&. This term refers to
   2082 the ability of a balancer to route a conversation between browser and
   2083 a backend farm always to the same back end\&. In other words: once a
   2084 back end is selected by the balancer, it will remain the back end of
   2085 choice, even for subsequent connections\&.
   2086 .PP 
   2087 
   2088 .SH "5\&.3\&.1: Don\&'t use stickiness!"
   2089 
   2090 .PP 
   2091 The rule of thumb as far as the balancer is concerned, is: \fBDo not
   2092 use HTTP session stickiness unless you really have to\&.\fP Enabling
   2093 session stickiness hampers failover, balancing and performance:
   2094 .PP 
   2095 .IP o 
   2096 Failover is hampered because during the session,
   2097 the balancer has to assign new connections to the same back
   2098 end that was selected at the start of a session\&. If the back
   2099 end suddenly goes \&'down\&', then the session will most likely
   2100 crash\&. (Actually, when a back end becomes unreachable in the
   2101 middle of a session, Crossroads will assign a new back end to
   2102 that session\&. This will most likely result in a malfunction
   2103 of the underlying application\&.)
   2104 .IP o 
   2105 Balancing is hampered because at the start of the session,
   2106 the balancer has selected the next-best back end\&. But during
   2107 the session, that back end may well become overloaded\&. The
   2108 balancer however must continue to send the requests there\&.
   2109 .IP o 
   2110 Performance is hampered because crossroads needs to \&'unpack\&'
   2111 messages as they are passed to and fro\&. That\&'s because
   2112 crossroads needs to check the HTTP headers in the messages
   2113 for persistence cookies\&.
   2114 .PP 
   2115 There is a number of measures that you can take to avoid using session
   2116 stickiness\&. E\&.g\&., session data can be \&'shared\&' between web back
   2117 ends\&. PHP offers functionality to store session data in a database, so
   2118 that all PHP applications have access to these data\&. Application
   2119 servers such as Websphere can be configured to replicate session data
   2120 between nodes\&.
   2121 .PP 
   2122 
   2123 .SH "5\&.3\&.2: But if you must\&.\&."
   2124 
   2125 .PP 
   2126 However, if you \fBmust\fP use session stickiness, then proceed as
   2127 follows:
   2128 .PP 
   2129 .IP o 
   2130 At the level of a \f(CWservice\fP description, set the type to
   2131 \f(CWhttp\fP\&. 
   2132 .IP o 
   2133 At the level of each back end description, configure the
   2134 \f(CWstickycookie\fP and a \f(CWaddclientheader\fP directives\&.
   2135 .PP 
   2136 Once crossroads sees that, it will examine each HTTP message that it
   2137 shuttles between client and back end:
   2138 .PP 
   2139 .IP o 
   2140 If there is no persistence cookie in the HTTP headers of a
   2141 client\&'s request, then the message must be the first one and
   2142 a new session should be established\&. 
   2143 Crossroads selects an appropriate back
   2144 end, sends the message to that back end, catches the reply,
   2145 and inserts a \f(CWSet-Cookie\fP directive\&.
   2146 .IP o 
   2147 If there is a persistence cookie in the HTTP headers of a
   2148 client\&'s request, then the request is part of an already
   2149 established session\&. Crossroads analyzes the cookie and
   2150 forwards the request to the appropriate back end\&.
   2151 .PP 
   2152 Below is a short example of a configuration\&.
   2153 .PP 
   2154 .nf 
   2155 service www {
   2156     port 80;
   2157     type http;
   2158     revivinginterval 15;
   2159     dispatchmode byconnections;
   2160 
   2161     backend one {
   2162         server 10\&.1\&.1\&.100:80;
   2163         stickycookie XRID=100;
   2164         addclientheader "Set-Cookie: XRID=100; Path=/";
   2165     }
   2166 
   2167     backend two {
   2168         server 10\&.1\&.1\&.101:80;
   2169         stickycookie XRID=101;
   2170         addclientheader "Set-Cookie: XRID=101; Path=/";
   2171     }
   2172 }
   2173 .fi 
   2174 
   2175 .PP 
   2176 Note how the cookie names and values in the directives
   2177 \f(CWstickycookie\fP and \f(CWaddclientheader\fP match\&. That is obviously a
   2178 prerequisite for stickiness\&.
   2179 .PP 
   2180 
   2181 .SH "5\&.4: Passing the client\&'s IP address"
   2182 
   2183 .PP 
   2184 Since Crossroads just shuttles bytes to and fro, meta-information of
   2185 network connections is lost\&. As far as the back ends are concerned,
   2186 their connections originate at the Crossroads junction\&.
   2187 For example, standard Apache access logs will show the IP address of
   2188 Crossroads\&. 
   2189 .PP 
   2190 In order to compensate for this, Crossroads can insert a special
   2191 header in HTTP connections, to inform the back end of the original
   2192 client\&'s IP address\&. In order to enable this, the Crossroads
   2193 configuration must state the following:
   2194 .PP 
   2195 .IP o 
   2196 The service type must be \f(CWhttp\fP, and not \f(CWany\fP;
   2197 .IP o 
   2198 In the back end definition, the following statement must
   2199 occur: 
   2200 .br 
   2201 \f(CWaddserverheader "X-Real-IP: %r";\fP 
   2202 .br 
   2203 You are of course free to choose the header name; the here
   2204 used \f(CWX-Real-IP\fP is a common name for this purpose\&.
   2205 .PP 
   2206 After this, HTTP traffic that arrives at the back ends has a new
   2207 header: \f(CWX-Real-IP\fP, holding the client\&'s IP address\&.
   2208 \fBNote that\fP once the type is set to \f(CWhttp\fP, Crossroads\&'
   2209 performance will be hampered -- all passing messages will have to be
   2210 unpacked and analyzed\&.
   2211 .PP 
   2212 
   2213 .SH "5\&.4\&.1: Sample Crossroads configuration"
   2214 
   2215 .PP 
   2216 The below sample configuration shows two HTTP back ends that receive
   2217 the client\&'s IP address:
   2218 .PP 
   2219 .nf 
   2220 
   2221 service www {
   2222     port 80;
   2223     type http;
   2224     revivinginterval 5;
   2225     dispatchmode roundrobin;
   2226 
   2227     backend one {
   2228         server 10\&.1\&.1\&.100:80;
   2229         addserverheader "X-Real-IP: %r";
   2230     }
   2231 
   2232     backend two {
   2233         server 10\&.1\&.1\&.200:80;
   2234         addserverheader "X-Real-IP: %r";
   2235     }
   2236 }
   2237 .fi 
   2238 
   2239 .PP 
   2240 
   2241 .SH "5\&.4\&.2: Sample Apache configuration"
   2242 
   2243 .PP 
   2244 The method by which each back end analyzes the header \f(CWX-Real-IP\fP
   2245 will obviously be different per server implementations\&. However, a
   2246 common method with the Apache webserver is to log the client\&'s IP
   2247 address into the access log\&.
   2248 .PP 
   2249 Often this is accomplished using the log format \f(CWcustom\fP, defined as
   2250 follows:
   2251 .PP 
   2252 .nf 
   2253 LogFormat "%h %l %u %t %D \e"%r\e" %>s %b" common
   2254 CustomLog logs/access_log common
   2255 .fi 
   2256 
   2257 .PP 
   2258 The first line defines the format \f(CWcommon\fP, with the remote host
   2259 specified by \f(CW%h\fP\&. The second line sends access information to a log
   2260 file \f(CWlogs/access_log\fP, using the previously defined format
   2261 \f(CWcommon\fP\&.
   2262 .PP 
   2263 Furtunately, Apache\&'s \f(CWLogFormat\fP allows one to log contents of
   2264 headers\&. By replacing the \f(CW%h\fP with \f(CW%{X-Real-IP}i\fP, the desired
   2265 information is sent to the log\&. Therefore, normally you can simply
   2266 redefine the \f(CWcommon\fP format to 
   2267 .PP 
   2268 .nf 
   2269 LogFormat "%{X-Real-IP}i %l %u %t %D \e"%r\e" %>s %b" common
   2270 .fi 
   2271 
   2272 .PP 
   2273 
   2274 .SH "5\&.5: Debugging network traffic"
   2275 
   2276 .PP 
   2277 Incase the traffic between
   2278 client and backend
   2279 must be debugged, the statement \f(CWtrafficlog\fP \fIfilename\fP can
   2280 be issued\&. This causes the traffic to be dumped in hexadecimal
   2281 format to the stated filename\&.
   2282 .PP 
   2283 Traffic sent by the client is prefixed by a \fBC\fP, traffic sent by
   2284 the back end is prefixed by a \fBB\fP\&. Below is a sample traffic
   2285 dump of a browser trying to get a HTML page\&. The server replies
   2286 that the page was not modified\&.
   2287 .PP 
   2288 .nf 
   2289 C 0000  47 45 54 20 68 74 74 70 3a 2f 2f 77 77 77 2e 63 GET http://www\&.c
   2290 C 0010  73 2e 68 65 6c 73 69 6e 6b 69 2e 66 69 2f 6c 69 s\&.helsinki\&.fi/li
   2291 C 0020  6e 75 78 2f 6c 69 6e 75 78 2d 6b 65 72 6e 65 6c nux/linux-kernel
   2292 C 0030  2f 32 30 30 31 2d 34 37 2f 30 34 31 37 2e 68 74 /2001-47/0417\&.ht
   2293 C 0040  6d 6c 20 48 54 54 50 2f 31 2e 31 0d 0a 43 6f 6e ml HTTP/1\&.1\&.\&.Con
   2294 C 0050  6e 65 63 74 69 6f 6e 3a 20 63 6c 6f 73 65 0d 0a nection: close\&.\&.
   2295 \&.
   2296 \&. etcetera
   2297 \&.
   2298 B 0000  48 54 54 50 2f 31 2e 30 20 33 30 34 20 4e 6f 74 HTTP/1\&.0 304 Not
   2299 B 0010  20 4d 6f 64 69 66 69 65 64 0d 0a 44 61 74 65 3a  Modified\&.\&.Date:
   2300 B 0020  20 54 75 65 2c 20 31 32 20 4a 75 6c 20 32 30 30  Tue, 12 Jul 200
   2301 B 0030  35 20 30 39 3a 34 39 3a 34 37 20 47 4d 54 0d 0a 5 09:49:47 GMT\&.\&.
   2302 B 0040  43 6f 6e 74 65 6e 74 2d 54 79 70 65 3a 20 74 65 Content-Type: te
   2303 B 0050  78 74 2f 68 74 6d 6c 3b 20 63 68 61 72 73 65 74 xt/html; charset
   2304 \&.
   2305 \&. etcetera
   2306 \&.
   2307 .fi 
   2308 
   2309 .PP 
   2310 Turning on traffic dumps will \fIsignificantly\fP
   2311 slow down crossroads\&.
   2312 .PP 
   2313 Besides \f(CWtrafficlog\fP, there is also a directive
   2314 \f(CWthroughputlog\fP\&. This directive also takes one argument, a
   2315 filename\&. The file is appended, and the following information is
   2316 logged:
   2317 .PP 
   2318 .IP o 
   2319 The process ID of the crossroads image that serves the
   2320 TCP connection;
   2321 .IP o 
   2322 The time of the request, in seconds and microseconds
   2323 since start of the run;
   2324 .IP o 
   2325 A \fBC\fP when the request originated at the client, or
   2326 \fBB\fP when the request originated at the back end;
   2327 .IP o 
   2328 The first 100 bytes of the request\&.
   2329 .PP 
   2330 As an example, consider the following (the lines are shortened for
   2331 brevity and prefixed by line numbers for clarity):
   2332 .PP 
   2333 .nf 
   2334 
   2335 1 0000594 0\&.000001 C GET http://public\&.e-tunity\&.com/index\&.html\&.\&.\&.
   2336 2 0000594 0\&.173713 B HTTP/1\&.0 200 OK\&.\&.Date: Fri, 18 Nov 2005 0\&.\&.\&.
   2337 3 0000594 0\&.278125 B  width="100" bgcolor="#e0e0e0" valign="to\&.\&.\&.
   2338 4 0000595 0\&.000001 C GET http://public\&.e-tunity\&.com/css/style/\&.\&.\&.
   2339 5 0000594 0\&.944339 B /a></td>\&.\&.  </tr>\&.</table>\&.</td><td class\&.\&.\&.
   2340 6 0000594 0\&.946356 B smallboxdownl">Download</td>\&.\&.  <td class\&.\&.\&.
   2341 7 0000594 0\&.961102 B td><td class="smallboxodd" valign="top"><\&.\&.\&.
   2342 8 0000595 0\&.698215 B HTTP/1\&.0 304 Not Modified\&.\&.Date: Fri, 18 \&.\&.\&.
   2343 .fi 
   2344 
   2345 .PP 
   2346 This tells us that:
   2347 .PP 
   2348 .IP o 
   2349 Line 1:  PID 594 served a request that originated at
   2350 the client\&. The corresponding time is (almost) 0 seconds,
   2351 so this is really the start of the run\&.
   2352 .IP o 
   2353 Line 2: A back end replied 0\&.17 seconds later, and
   2354 0\&.28 seconds later, it was still replying (this is the
   2355 third line, again a \fBB\fP-type transmission)\&.
   2356 .IP o 
   2357 Line 4: PID 595 served a request that originated
   2358 at the client\&. Again, the corresponding time is (almost)
   2359 0 seconds, since this is the first conversation part of
   2360 this connection\&.
   2361 .IP o 
   2362 Lines 5 to 7: This is the continuation of line 2\&. Line 7
   2363 is the last line of the \fBB\fP series (not visible from
   2364 the example, but trust me, it is), so that we may
   2365 conclude that it took the back end 0\&.96 seconds to serve
   2366 the file \f(CWindex\&.html\fP requested in line 1\&.
   2367 .IP o 
   2368 Line 8: This is the answer to the client\&'s request of
   2369 line 4 (you can tell by the process ID  number)\&.
   2370 So the back end took 0\&.68 seconds to confirm that
   2371 the stylesheet requested in line 4 wasn\&'t modified\&.
   2372 .PP 
   2373 It is also worth while remembering that the start time of a \fBC\fP
   2374 request is the time that crossroads sees the activity\&. Any latency
   2375 between the true client and crossroads is obviously not
   2376 included\&. This is illustrated by the below simple ASCII art:
   2377 .PP 
   2378 .nf 
   2379 
   2380 client ---->---->---->--->*crossroads ====>====>====>
   2381                                                      \e    
   2382                                                   back end
   2383                                                      /
   2384 client ----<----<----<---< crossroads ====<====<====<
   2385 
   2386 .fi 
   2387 
   2388 .PP 
   2389 This simple picture shows a typical HTTP request that originates
   2390 at a client, travels to crossroads, and is relayed via the back
   2391 end\&. The \fBC\fP entry in a throughput log is the time when
   2392 crossroads sees the request, indicated by an asterisk\&. The \fBB\fP
   2393 entries are the times that it takes the back end to answer,
   2394 indicated by \f(CW===\fP style lines\&. Therefore, the true roundtrip
   2395 time will be longer than the number of seconds that are logged in
   2396 the throughput log: the latency between client and crossroads
   2397 isn\&'t included in that measurement\&.
   2398 .PP 
   2399 Summarizing, the throughput times of a client-back end connection
   2400 can be analyzed using the directive \f(CWthroughputlog\fP\&. In a
   2401 real-world analysis, you\&'d probably want to write up a script to
   2402 analyze the output and to compute round trip times\&. Such scripts
   2403 are not (yet) included in Crossroads\&.
   2404 .PP 
   2405 
   2406 .SH "5\&.6: Limiting Access to Crossroads by Client IP Address"
   2407 
   2408 .PP 
   2409 
   2410 .SH "5\&.6\&.1: General Examples"
   2411 
   2412 .PP 
   2413 The directives \f(CWallowfrom\fP, \f(CWdenyfrom\fP, \f(CWallowfile\fP and
   2414 \f(CWdenyfile\fP can be used to instruct Crossroads to specifically allow
   2415 access by using a "whitelist" of IP addresses, or to specifically deny
   2416 access by using a "blacklist"\&. E\&.g\&., the following configuration
   2417 allows access to service \f(CWwebproxy\fP only to \fIlocalhost\fP:
   2418 .PP 
   2419 .nf 
   2420 service webproxy {
   2421     port 8000;    
   2422     allowfrom 127\&.0\&.0\&.1;
   2423     backend one {
   2424         \&.
   2425         \&. Back end definitions occur here
   2426         \&.
   2427     }
   2428     \&.
   2429     \&. Other back ends or other service directives
   2430     \&. may occur here
   2431     \&.
   2432 }
   2433 .fi 
   2434 
   2435 .PP 
   2436 In this example there is a "whitelist" having only one entry: IP
   2437 address 127\&.0\&.0\&.1, or \fIlocalhost\fP\&. (Incidentally, the same behaviour
   2438 could be accomplished by stating \fIbindto 127\&.0\&.0\&.1\fP, in which case
   2439 Crossroads would only listen to the local network device\&.)
   2440 .PP 
   2441 In the same vein, the directive \f(CWallowfrom 127\&.0\&.0\&.1 192\&.168\&.1/24\fP
   2442 would allow access to \fIlocalhost\fP and to all IP addresses that start
   2443 with 192\&.168\&.1\&. The specifier \f(CW192\&.168\&.1/24\fP states that there are
   2444 three network bytes (192, 168 and 1), and 24 bits (or 3 bytes) are
   2445 relevant; so that the fourth network byte doesn\&'t matter\&.
   2446 .PP 
   2447 
   2448 .SH "5\&.6\&.2: Using External Files"
   2449 
   2450 .PP 
   2451 The directives \f(CWallowfile\fP and \f(CWdenyfile\fP allow you to specify IP
   2452 addresses in external files\&. The Crossroads configuration states
   2453 e\&.g\&. \f(CWallowfile /tmp/allow\&.txt\fP, and the IP addresses are then in
   2454 \f(CW/tmp/allow\&.txt\fP\&. The format of \f(CW/tmp/allow\&.txt\fP is as follows:
   2455 .PP 
   2456 .IP o 
   2457 The specifications follow again \fIp\&.q\&.r\&.s/mask\fP, where
   2458 p, q, r and s are network bytes which can be left out on the
   2459 right hand side when the mask allows it;
   2460 .IP 
   2461 .IP o 
   2462 The specifications must be separated by white space
   2463 (spaces, tabs or newlines)\&.
   2464 .PP 
   2465 E\&.g\&., the following is a valid example of an external specification
   2466 file:
   2467 .PP 
   2468 .nf 
   2469 127\&.0\&.0\&.1
   2470 192\&.168\&.1/24
   2471 10/8
   2472 .fi 
   2473 
   2474 .PP 
   2475 When external files are in effect, then the signal \f(CWSIGHUP\fP (1)
   2476 causes Crossroads to reload the external file\&. E\&.g\&., while Crossroads
   2477 is running, you may edit \f(CW/tmp/allow\&.txt\fP, and then issue \f(CWkillall
   2478 -1 crossroads\fP\&. The new contents of \f(CW/tmp/allow\&.txt\fP will be
   2479 reloaded\&.
   2480 .PP 
   2481 
   2482 .SH "5\&.6\&.3: Mixing Directives"
   2483 
   2484 .PP 
   2485 Crossroads allows to mix all directives in one service
   2486 description\&. However, some mixes are less meaningful than others\&. It\&'s
   2487 up to you to take this into account\&.
   2488 .PP 
   2489 The following rules apply:
   2490 .PP 
   2491 .IP o 
   2492 Blacklisting and whitelisting can be used together\&. When
   2493 combined, the blacklist will always be interpreted
   2494 first\&. E\&.g\&., consider the following directives:
   2495 .IP 
   2496 .nf 
   2497 allowfrom 192\&.168\&.1/24
   2498 denyfrom  192\&.168\&.1\&.100
   2499 .fi 
   2500 
   2501 .IP 
   2502 Given the fact that the deny list is checked first, client
   2503 192\&.168\&.1\&.100 won\&'t be able to access Crossroads\&. Then the
   2504 allow list will be checked, stating that all clients whose IP
   2505 address starts with 192\&.168\&.1 may connect\&. The effect will be
   2506 that e\&.g\&., client 192\&.168\&.1\&.1 may connect, 192\&.168\&.1\&.2 may
   2507 connect too, 192\&.168\&.1\&.100 will be blocked, and 10\&.1\&.1\&.1 will
   2508 be blocked as well\&.
   2509 .IP 
   2510 Now consider the following directives:
   2511 .IP 
   2512 .nf 
   2513 allowfrom 192\&.168\&.1\&.100 127\&.0\&.0\&.1
   2514 denyfrom  192\&.168\&.1/24
   2515 .fi 
   2516 
   2517 .IP 
   2518 This will first of all deny access to all IP addresses that
   2519 start with 192\&.168\&.1\&. So the rule that allows 192\&.168\&.1\&.100
   2520 won\&'t ever be effective\&. The net result will be that access
   2521 will be granted to 127\&.0\&.0\&.1, and IP addresses that don\&'t
   2522 match 192\&.168\&.1/24\&.
   2523 .IP 
   2524 .IP o 
   2525 Blacklisting or whitelisting can be left out\&.
   2526 A list is considered empty when no appropriate directives
   2527 occur in \f(CW/etc/crossroads\&.conf\fP, or when the directive
   2528 points to an empty or non-existent external file\&.
   2529 .IP 
   2530 .IP o 
   2531 Using \f(CW*from\fP and \f(CW*file\fP statements is allowed, but
   2532 doesn\&'t make sense\&. E\&.g\&., the following configuration sample
   2533 is such a case:
   2534 .IP 
   2535 .nf 
   2536 allowfrom 127\&.0\&.0\&.1 192\&.168\&.1/24
   2537 allowfile /tmp/allow\&.txt
   2538 .fi 
   2539 
   2540 .IP 
   2541 There is a technical reason for this\&. Once Crossroads
   2542 processes the \f(CWallowfile\fP directive, then the whole
   2543 whitelist is cleared (thereby removing the entries 127\&.0\&.0\&.1
   2544 and 192\&.168\&.1/24), and new entries are reloaded from the
   2545 file\&. The net result is that the \f(CWallowfrom\fP specification
   2546 is overruled\&.
   2547 .IP 
   2548 Crossroads doesn\&'t check for such configurations, which are
   2549 syntactially correct, but make no semantic sense\&.
   2550 .PP 
   2551 
   2552 .SH "5\&.7: Configuration examples"
   2553 
   2554 .PP 
   2555 As a general hint, use \f(CWcrossroads sampleconf\fP to view the most
   2556 up-to-date examples of configurations\&. The description below shows a
   2557 few examples too\&.
   2558 .PP 
   2559 
   2560 .SH "5\&.7\&.1: A load balancer for three webserver back ends"
   2561 
   2562 .PP 
   2563 The following configuration example binds crossroads to port 80 of the
   2564 current server, and distributes the load over three back ends\&. This
   2565 configuration shows most of the possible settings\&.
   2566 .PP 
   2567 .nf 
   2568 service www {
   2569     /* We don\&'t need session stickyness\&. */
   2570     type any;
   2571     
   2572     /* Port on which we\&'ll listen in this service: required\&. */
   2573     port 8000;
   2574 
   2575     /* What IP address should this service listen? Default is \&'any\&'\&.
   2576      * Alternatively you can state an explicit IP address, such as
   2577      * 127\&.0\&.0\&.1; that would bind the service only to \&'localhost\&'\&. */
   2578     bindto any;
   2579     
   2580     /* Verbose reporting or not\&. Default is off\&. */    
   2581     verbosity on;
   2582     
   2583     /* Dispatching mode, or: How to select a back end for an incoming
   2584      * request\&. Possible values:
   2585      *   roundrobin: just the next back end in line
   2586      *   random: like roundrobin, but at random to make things more
   2587      *          confusing\&. Probably only good for testing\&.
   2588      *   bysize: The backend that transferred the least nr of bytes
   2589      *          is the next in line\&. As a modifier you can say e\&.g\&.
   2590      *          bysize over 10, meaning that the 10 last connections will
   2591      *          be used to compute the transfer size, instead of all
   2592      *          transfers\&.
   2593      *   byduration: The backend that was active for the shortest time
   2594      *          is the next in line\&. As a modifier you can say e\&.g\&.
   2595      *          byduration of 10 to compute over the last 10 connections\&.
   2596      *   byconnections: The back end with the least active connections
   2597      *          is the next ine line\&.
   2598      *   byorder: The first available back end is always taken\&.
   2599      */
   2600     dispatchmode byduration over 5;
   2601 
   2602     /* Interval at which we\&'ll check whether a temporarily unavailable
   2603      * backend has woken up\&.
   2604      */
   2605     revivinginterval 5;
   2606     
   2607     /* TCP backlog of connections\&. Default is 0 (no backlog, one
   2608      * connection may be active)\&.
   2609      */
   2610     backlog 5;
   2611     
   2612     /* For status reporting: a shared memory key\&. Default is the same
   2613      * as the port number, OR-ed by a magic number\&.
   2614      */
   2615     shmkey 8000;
   2616 
   2617     /* This controls when crossroads should consider a connection as
   2618      * finished even when the TCP sockets weren\&'t closed\&. This is to
   2619      * avoid hanging connections that don\&'t do anything\&. NOTE THAT when
   2620      * crossroads cuts off a connection due to timeout exceed, this is
   2621      * not marked as a failure, but as a success\&. Default is 0: no timeout\&.
   2622      */
   2623     connectiontimeout 300;
   2624 
   2625     /* The max number of allowed client connections\&. When present, connections
   2626      * won\&'t be accepted if the max is about to be exceeded\&. When
   2627      * absent, all connections will be accepted, which might be misused
   2628      * for a DOS attack\&.
   2629      */
   2630     maxconnections 300;
   2631 
   2632     /* Now let\&'s define a couple of back ends\&. Number 1: */
   2633     backend www_backend_1 {
   2634         /* The server and its port, the minimum configuration\&. */
   2635         server httpserver1;
   2636         port 9010;
   2637         /* The \&'decay\&' of usage data of this back end\&. Only relevant
   2638          * when the whole service has \&'dispatchmode bysize\&' or
   2639          * \&'byduration\&'\&. The number is a percentage by which the usage
   2640          * parameter is decreased upon each connection of an other back
   2641          * end\&.
   2642          */
   2643         decay 10;
   2644         
   2645         /* To see what\&'s happening in /var/log/messages: */
   2646         verbosity on;
   2647     }
   2648 
   2649     /* The second one: */
   2650     backend www_backend_2 {
   2651         /* Server and port */
   2652         server httpserver2;
   2653         port 9011;
   2654 
   2655         /* Verbosity of reporting when this back end is active */
   2656         verbosity on;
   2657 
   2658         /* Decay */
   2659         decay 10;
   2660 
   2661         /* This back end is twice as weak as the first one */
   2662         weight 2;
   2663 
   2664         /* Event triggers for system commands upon succesful activation
   2665          * and upon failure\&.
   2666          */
   2667         onsuccess echo \&'success on backend 2\&' | mail root;
   2668         onfailure echo \&'failure on backend 2\&' | mail root;
   2669     }
   2670 
   2671     /* And yet another one\&.\&. this time we will dump the traffic
   2672      * to a trace file\&. Furthermore we don\&'t want more than 10 concurrent
   2673      * connections here\&. Note that there\&'s also a total maxconnections for the
   2674      * whole service\&.
   2675      */
   2676     backend www_backend_3 {
   2677         server httpserver3;
   2678         verbosity on;
   2679         port 9000;
   2680         verbosity on;
   2681         decay 10;
   2682         trafficlog /tmp/backend\&.3\&.log;
   2683         maxconnections 10;
   2684     }
   2685 }
   2686 .fi 
   2687 
   2688 .PP 
   2689 
   2690 .SH "5\&.7\&.2: An HTTP forwarder when travelling"
   2691 
   2692 .PP 
   2693 As another example, here\&'s my \f(CWcrossroads\&.conf\fP that I use on my
   2694 Unix laptop\&. The problem that I face is that I need many HTTP proxy
   2695 configurations (at home, at customers\&' sites and so on) but I\&'m too
   2696 lazy to reconfigure browsers all the time\&.
   2697 .PP 
   2698 Here\&'s how it used to be before crossroads:
   2699 .PP 
   2700 .IP o 
   2701 At home, I would surf through a squid proxy on my local
   2702 machine\&. The browser proxy setting is then
   2703 \f(CWhttp://localhost:3128\fP\&.
   2704 .IP 
   2705 .IP o 
   2706 Sometimes I start up an SSH tunnel to our offices\&. The
   2707 tunnel has a local port 3129, and connects to a squid proxy on
   2708 our e-tunity server\&. Hence, the browser proxy is then
   2709 \f(CWhttp://localhost:3129\fP\&.
   2710 .IP 
   2711 .IP o 
   2712 At a customer\&'s location I need the proxy
   2713 \f(CWhttp://10\&.120\&.34\&.113:8080\fP, because they have configured it
   2714 so\&.
   2715 .IP 
   2716 .IP o 
   2717 And in yet other instances, I use a HTTP diagnostic tool
   2718 Charles
   2719 that sits between browser and website and shows me
   2720 what\&'s happening\&. I run charles on my own machine and it
   2721 listens to port 8888, behaving like a proxy\&. The browser
   2722 configuration for the proxy is then
   2723 \f(CWhttp://localhost:8888\fP\&.
   2724 .PP 
   2725 Here\&'s how it works with a crossroads configuration:    
   2726 .PP 
   2727 .IP o 
   2728 I have configured my browsers to use
   2729 \f(CWhttp://localhost:8080\fP as the proxy\&. For all situations\&.
   2730 .IP 
   2731 .IP o 
   2732 I use the following crossroads configuration, and let
   2733 crossroads figure out which proxy backend works, and which
   2734 doesn\&'t\&. Note two particularities:
   2735 .IP 
   2736 .IP o 
   2737 The statement \f(CWdispatchmode byorder\fP\&. This
   2738 makes sure that once crossroads determines which
   2739 backend works, it will stick to it\&. This usage of
   2740 crossroads doesn\&'t need to balance over more than one
   2741 back end\&.
   2742 .IP 
   2743 .IP o 
   2744 The statement \f(CWbindto 127\&.0\&.0\&.1\fP makes sure
   2745 that requests from other interfaces than loopback
   2746 won\&'t get serviced\&.
   2747 .IP 
   2748 .nf 
   2749 service HttpProxy {
   2750     port 8080;
   2751     bindto 127\&.0\&.0\&.1;
   2752     verbosity on;
   2753     dispatchmode byorder;
   2754     revivinginterval 15;
   2755 
   2756     backend Charles {
   2757         server localhost:8888;
   2758         verbosity on;
   2759     }
   2760 
   2761     backend CustomerProxy {
   2762         server 10\&.120\&.34\&.113:8080;
   2763         verbosity on;
   2764     }
   2765 
   2766     backend SshTunnel {
   2767         server localhost:3129;
   2768     }
   2769 
   2770     backend LocalSquid {
   2771         server localhost:3128;
   2772     }
   2773 }
   2774 .fi 
   2775 
   2776 .PP 
   2777 As a final note, the commandline argument \f(CWtell\fP can be used to
   2778 influence crossroad\&'s own detection mechanism of back end availability
   2779 detection\&. E\&.g\&., if in the above example the back ends \f(CWSshTunnel\fP
   2780 and \f(CWLocalSquid\fP are both active, then \f(CWcrossroads tell httpproxy
   2781 sshtunnel down\fP will \&'take down\&' the back end \f(CWSshTunnel\fP -- and
   2782 will automatically cause crossroads to switch to \f(CWLocalSquid\fP\&.
   2783 .PP 
   2784 
   2785 .SH "5\&.7\&.3: SSH login with enforced idle logout"
   2786 
   2787 .PP 
   2788 The following example shows how crossroads \&'throttles\&' SSH
   2789 logins\&. Connections are accepted on port
   2790 22 (the normal SSH port) and forwarded to the actual SSH daemon
   2791 which is running on port 2222\&.
   2792 .PP 
   2793 Note the usage of the
   2794 \f(CWconnectiontimeout\fP directive\&. This makes sure that users are logged
   2795 out after 10 minutes of inactivity\&. Note also the \f(CWmaxconnections\fP
   2796 setting, this makes sure that no more than 10 concurrent logins occur\&.
   2797 .PP 
   2798 .nf 
   2799 service Ssh {
   2800     port 22;
   2801     backlog 5;
   2802     maxconnections 10;
   2803     connectiontimeout 600;
   2804     backend TrueSshDaemon {
   2805         server localhost:2222;
   2806     }
   2807 }
   2808 .fi 
   2809 
   2810 .PP 
   2811 
   2812 .SH "6: Benchmarking"
   2813 This section shows how crossroads affects the
   2814 transmitting of HTML data when used as an intermediate \&'station\&'
   2815 through which all data travels\&.
   2816 .PP 
   2817 
   2818 .SH "6\&.1: Benchmark 1: Accessing a proxy via crossroads or directly"
   2819 
   2820 .PP 
   2821 The benchmark was run on a system where the following was varied:
   2822 .PP 
   2823 .IP 1\&.
   2824 A website was recursively spidered through a local squid
   2825 proxy\&. The spidering was repeated 10 times, the total was recorded\&.
   2826 .IP 
   2827 .IP 2\&.
   2828 Crossroads was placed in front of the squid proxy, and
   2829 the website was again recursively spidered\&. Again, the
   2830 spidering was repeated 10 times and the total was recorded\&.
   2831 .PP 
   2832 The crossroads configuration of the second alternative is shown below:
   2833 .PP 
   2834 .nf 
   2835 service HttpProxy {
   2836     port 8080;
   2837     verbosity on;
   2838     backend LocalSquid {
   2839         server 127\&.0\&.0\&.1;
   2840         port 3128;
   2841         verbosity on;
   2842     }
   2843 }
   2844 .fi 
   2845 
   2846 .PP 
   2847 
   2848 .SH "6\&.1\&.1: Results"
   2849 
   2850 .PP 
   2851 The results of this test are that crossroads causes a negligible
   2852 delay, if it is statistically relevant at all\&. Without crossroads, the
   2853 timing results are:
   2854 .PP 
   2855 .nf 
   2856 real	0m8\&.146s
   2857 user	0m0\&.130s
   2858 sys	0m0\&.253s
   2859 .fi 
   2860 
   2861 .PP 
   2862 When using crossroads as a middle station, the results are:
   2863 .PP 
   2864 .nf 
   2865 real	0m9\&.481s
   2866 user	0m0\&.141s
   2867 sys	0m0\&.230s
   2868 .fi 
   2869 
   2870 .PP 
   2871 
   2872 .SH "6\&.1\&.2: Discussion"
   2873 
   2874 .PP 
   2875 The above shown results are quite favorable to crossroads\&. However,
   2876 one should know that situations will exist where crossroads leans
   2877 towards the \&'worst case\&' scenario, causing up to 50%
   2878 delay\&.
   2879 .PP 
   2880 E\&.g\&., imagine a test where a \f(CWwget\fP command retrieves a
   2881 HTML document from an Apache server on \f(CWlocalhost\fP\&. Now we have
   2882 (almost) no overhead due to network throttling, hostname lookups and
   2883 so on\&. When this test would be run either with or without crossroads
   2884 in between, then theoretically, crossroads would cause a much larger
   2885 delay, because it has to read from the server, and then write the same
   2886 information to \f(CWwget\fP\&.  Each read/write occurs twice when crossroads
   2887 sits in between\&.
   2888 .PP 
   2889 This worst case scenario will however (fortunately) occur only very
   2890 seldom in the real world:
   2891 .PP 
   2892 .IP o 
   2893 Normally network issues, such as the above mentioned host
   2894 name lookups or throughput restrictions, will add
   2895 significantly to the duration of a request\&. The \&'twice as
   2896 many\&' read/writes caused by crossroads are then relatively
   2897 irrelevant\&.
   2898 .IP 
   2899 .IP o 
   2900 Normally a significant amount of time will be spent in a
   2901 back end, due to processing (e\&.g\&., when calling a servlet on a
   2902 back end)\&. Again, this processing time will weigh much heavier
   2903 than the multiple read/writes\&.
   2904 .PP 
   2905 
   2906 .SH "6\&.2: Benchmark 2: Crossroads versus Linux Virtual Server (LVS)"
   2907 
   2908 .PP 
   2909 LVS is a kernel-based balancer that acts like a masquerading
   2910 firewall: TCP packets that arrive at the balancer are sent to one of
   2911 the configured back ends\&. LVS has the advantage over crossroads that
   2912 there is no stop-and-go in the transmission; in contrast, crossroads
   2913 needs to send data via an internal buffer\&. Crossroads has the
   2914 advantage that it offers instantaneous failover because it tries to
   2915 contact the back end for upon each new TCP connection; in contrast,
   2916 LVS isn\&'t aware of downtime of back ends (unless one implements an
   2917 external heartbeat)\&. Also, crossroads offers more complex balancing
   2918 than LVS\&.
   2919 .PP 
   2920 
   2921 .SH "6\&.2\&.1: Environment"
   2922 
   2923 .PP 
   2924 On the balancer, LVS was run on port 80, its forwarding set up for two
   2925 equally weighted back ends, using \f(CWipvsadm\fP:
   2926 .PP 
   2927 .nf 
   2928 ipvsadm -a -t 192\&.168\&.1\&.250:http -r 10\&.1\&.1\&.100:http -m -w 1
   2929 ipvsadm -a -t 192\&.168\&.1\&.250:http -r 10\&.1\&.1\&.101:http -m -w 1
   2930 .fi 
   2931 
   2932 .PP 
   2933 Crossroads was run on port 81\&. The configuration file is shown below:
   2934 .PP 
   2935 .nf 
   2936 service http {
   2937     port 81;
   2938     dispatchmode roundrobin;
   2939     revivinginterval 5;
   2940     backend one {
   2941         server 10\&.1\&.1\&.100;
   2942         port 80;
   2943     }
   2944     backend two {
   2945         server 10\&.1\&.1\&.101;
   2946         port 80;
   2947     }
   2948 }
   2949 .fi 
   2950 
   2951 .PP 
   2952 
   2953 .SH "6\&.2\&.2: Tests and results"
   2954 
   2955 .PP 
   2956 In the first test, ports 80 and 81 on the balancer were \&'bombed\&' with
   2957 50 concurrent clients, each requesting a small page 50 times\&. The
   2958 following timings where measured:
   2959 .PP 
   2960 .IP o 
   2961 How long it takes to establish a connection;
   2962 .IP o 
   2963 How long it takes to retrieve the page\&.
   2964 .PP 
   2965 The results of this test were:
   2966 .PP 
   2967 .IP o 
   2968 On average, each client took 0\&.12 seconds to connect
   2969 to LVS, and each page was retrieved in 0\&.14 seconds;
   2970 .IP o 
   2971 On average, each client took 0\&.11 seconds to connect to
   2972 crossroads, and each page was retrieved in 0\&.13 seconds\&.
   2973 .PP 
   2974 In this setup there seems to be no difference between the performance
   2975 of LVS and crossroads!
   2976 .PP 
   2977 In a second test, the size of the retrieved page was varied from 2\&.000
   2978 to 2\&.000\&.000 bytes\&. This test was taken to see whether crossroads would
   2979 show performance degradation when transferring larger amounts of data\&.
   2980 .PP 
   2981 For each page size, 30 concurrent clients were started, that retrieved
   2982 the page 50 times\&. Again, the connect times and processing times where
   2983 recorded\&.
   2984 .PP 
   2985 The results of the total time (connect time + retrieval time)
   2986 are shown in the below table:
   2987 .PP 
   2988 .TS 
   2989  tab(~);
   2990 
   2991 
   2992 
   2993 
   2994 
   2995 
   2996 
   2997 
   2998 
   2999 
   3000 
   3001 
   3002 ---
   3003 rrr
   3004 rrr
   3005 rrr
   3006 rrr
   3007 rrr
   3008 ---
   3009 c.
   3010 \fBBytes\fP~\fBLVS timing\fP~\fBCrossroads timing\fP
   3011 2000~0\&.130741688~0\&.12739582
   3012 20000~0\&.490916224~0\&.50376901
   3013 200000~3\&.799440328~4\&.33125273
   3014 2000000~45\&.25090855~45\&.9600728
   3015 .TE 
   3016 
   3017 .PP 
   3018 Again, the results show that crossroads performs just as effectively
   3019 as LVS, even with large data chunks!
   3020 .PP 
   3021 
   3022 .SH "7: Compiling and Installing"
   3023 
   3024 
   3025 .SH "7\&.1: Prerequisites"
   3026 
   3027 .PP 
   3028 The creation of crossroads requires:
   3029 .PP 
   3030 .IP o 
   3031 Standard Unix tools, such as \f(CWsed\fP, \f(CWawk\fP, \f(CWPerl\fP
   3032 (5\&.00 or better);
   3033 .IP 
   3034 .IP o 
   3035 A POSIX-compliant C compiler;
   3036 .IP 
   3037 .IP o 
   3038 Support for SYSV IPC, networking and so on\&.
   3039 
   3040 .PP 
   3041 Basically a Linux or Apple MacOSX box will do nicely\&. To compile and install
   3042 crossroads, follow these steps\&.
   3043 .PP 
   3044 
   3045 .SH "7\&.2: Compiling and installing"
   3046 
   3047 .PP 
   3048 .IP o 
   3049 Obtain the source distribution\&. It can be found on
   3050 http://crossroads\&.e-tunity\&.com\&. The distribution comes as an
   3051 archive \f(CWcrossroads-\fP\fItype\fP\f(CW\&.tar\&.gz\fP, where \fItype\fP is
   3052 \f(CWstable\fP or \f(CWdevel\fP\&.
   3053 .IP 
   3054 .IP o 
   3055 Unpack the archive in a sources directory using \f(CWtar
   3056 xzf crossroads-\fP\fIX\&.YY\fP\f(CW\&.tar\&.gz\fP\&. The contents spill into a
   3057 subdirectory \f(CWcrossroads-\fP\fIX\&.YY/\fP\&.
   3058 .IP 
   3059 .IP o 
   3060 Change-dir into the directory\&.
   3061 .IP 
   3062 .IP o 
   3063 Next, edit \f(CWetc/Makefile\&.def\fP and verify that all
   3064 compilation settings are to your likings\&. The settings are
   3065 explained in the file\&. \fBNote that\fP the default distribution
   3066 of \f(CWMakefile\&.def\fP is suited for Linux or Apple MacOSX
   3067 systems\&. On other Unices, or on non-Unix systems, you must
   3068 particularly pay attention to \f(CWSET_PROC_TITLE_BY\&.\&.\&.\fP\&. When
   3069 in doubt, comment out all \f(CWSET_PROC_TITLE\&.\&.\&.\fP
   3070 settings\&. Crossroads will work nevertheless, but it won\&'t show
   3071 nice titles in \f(CWps\fP listings\&. Also there\&'s a macro
   3072 \f(CWEXTRA_LIBS\fP to add linkage flags (an example for a Solaris
   3073 build is included)\&.
   3074 .IP 
   3075 .IP o 
   3076 Now crossroads is ready for compilation\&. Do a \f(CWmake
   3077 local\fP followed by \f(CWmake install\fP\&. The latter step may have
   3078 to be done by the user \f(CWroot\fP if the \f(CWBINDIR\fP setting of
   3079 \f(CWetc/Makefile\&.def\fP points to a root-owned directory\&.
   3080 .IP 
   3081 .IP o 
   3082 The documentation doesn\&'t install in this process\&. If you
   3083 want to install the documentation, then proceed as follows:
   3084 .IP 
   3085 .IP o 
   3086 Optionally, \f(CWcp doc/crossroads\&.html\fP
   3087 \fIhtmldirectory/\fP; where \fIhtmldirectory\fP is the destination
   3088 directory for your HTML manuals;
   3089 .IP 
   3090 .IP o 
   3091 Optionally, \f(CWcp doc/crossroads\&.pdf\fP
   3092 \fIpdfdirectory/\fP; where \fIpdfdirectory\fP is the
   3093 destination directory for your PDF manuals;
   3094 .IP 
   3095 .IP o 
   3096 Optionally, \f(CWcp doc/crossroads\&.man\fP
   3097 \fImanualdirectory\fP\f(CW/crossroads\&.1\fP, where
   3098 \fImanualdirectory\fP is e\&.g\&. \f(CW/usr/man/man1\fP,
   3099 \f(CW/usr/share/man1\fP, \f(CW/usr/local/man/man1\fP,
   3100 \f(CW/usr/local/share/man1\fP\&. Any possibility is valid, as
   3101 long as \fImanualdirectory\fP is one of the directories
   3102 where manual pages are stored;
   3103 .IP 
   3104 .IP o 
   3105 If your manual page system supports compressed
   3106 manual pages, then you can save some space with
   3107 \f(CWgzip\fP \fImanualdirectory\fP\f(CW/crossroads\&.1\fP\&.
   3108 .IP 
   3109 
   3110 .SH "7\&.3: Configuring crossroads"
   3111 
   3112 .PP 
   3113 Now that the binary is available on your system, you need to create a
   3114 suitable \f(CW/etc/crossroads\&.conf\fP\&. Use this manual or the output of
   3115 \f(CWcrossroads samplconf\fP to get started\&.
   3116 .PP 
   3117 Once you have the configuration ready, start crossroads with
   3118 \f(CWcrossroads start\fP\&. Test the availability of your services and back
   3119 ends\&. Monitor how crossroads is doing with:
   3120 .PP 
   3121 .IP o 
   3122 In one terminal, run the script:
   3123 .nf 
   3124 while [ 1 ] ; do
   3125     tput clear
   3126     crossroads status
   3127     sleep 3
   3128 done
   3129 .fi 
   3130 
   3131 .IP 
   3132 \fBNote\fP that depending on your system you might need
   3133 \f(CWsleep 3s\fP, i\&.e\&., with an \f(CWs\fP appended\&.
   3134 .IP 
   3135 .IP o 
   3136 In another terminal, run:
   3137 .nf 
   3138 while [ 1 ] ; do
   3139     tput clear
   3140     ps ax | grep crossroads | grep -v grep
   3141     sleep 3		    	
   3142 done
   3143 .fi 
   3144 
   3145 .IP 
   3146 \fBNote\fP that depending on your system you might need
   3147 \f(CWps -ef\fP instead of \f(CWps ax\fP\&.
   3148 .IP 
   3149 .IP o 
   3150 In yet another terminal, run \f(CWtail -f
   3151 /var/log/messages\fP (supply the appropriate system log file if
   3152 \f(CW/var/log/messages\fP doesn\&'t work for you)\&.
   3153 .PP 
   3154 Now thoroughly test the availability of your back ends through
   3155 crossroads\&. The status display will show an updated view of which back
   3156 ends are selected and how busy they are\&. The process list will show
   3157 which crossroads daemons are running\&. Finally, the tailing of
   3158 \f(CW/var/log/messages\fP shows what\&'s going on -- especially if you have
   3159 \f(CWverbosity true\fP statements in the configuration\&.
   3160 .PP 
   3161 
   3162 .SH "7\&.4: A boot script"
   3163 
   3164 .PP 
   3165 Finally, you may want to create a boot-time startup script\&. The exact
   3166 procedure depends on the used Unix flavor\&.
   3167 .PP 
   3168 
   3169 .SH "7\&.4\&.1: SysV Style Startup"
   3170 
   3171 .PP 
   3172 On SysV style systems, there\&'s a startup script directory
   3173 \f(CW/etc/init\&.d\fP where bootscripts for all utilities are located\&.
   3174 You may have the \f(CWchkconfig\fP utility to automate the task of
   3175 inserting scripts into the boot sequence, but
   3176 otherwise the steps will resemble the following\&.
   3177 .PP 
   3178 .IP o 
   3179 Create a script \f(CWcrossroads\fP in \f(CW/etc/init\&.d\fP similar to the
   3180 following:
   3181 .IP 
   3182 .nf 
   3183 #!/bin/sh
   3184 /usr/local/bin/crossroads -v $@
   3185 .fi 
   3186 
   3187 .IP 
   3188 The stated directory \f(CW/usr/local/bin\fP must correspond with
   3189 the installation path\&. The flag \f(CW-v\fP causes the startup to
   3190 be more \&'verbose\&'\&. However, once daemonized, the verbosity is
   3191 controlled by the appropriate statements in the configuration\&.
   3192 .IP 
   3193 .IP o 
   3194 Determine your \&'runlevel\&': usually 3 when your system is
   3195 running in text-mode only, or 5 when you are using a graphical
   3196 interface\&. If your runlevel is 3, then:
   3197 .IP 
   3198 .nf 
   3199 root> cd /etc/rc\&.d/rc3\&.d
   3200 root> ln -s /etc/init\&.d/crossroads S99crossroads
   3201 root> ln -s /etc/init\&.d/crossroads K99crossroads
   3202 .fi 
   3203 
   3204 .IP 
   3205 This creates startup (\f(CWS*\fP) and stop (\f(CWK*\fP) links that
   3206 will be run when the system enters or leaves a given runlevel\&.
   3207 .IP 
   3208 If your runlevel is 5, then the right \f(CWcd\fP command is to
   3209 \f(CW/etc/rc\&.d/rc5\&.d\fP\&. Alternatively, you can create the
   3210 symlinks in both runlevel directories\&.
   3211 .PP 
   3212 
   3213 .SH "7\&.4\&.2: BSD Style Startup"
   3214 
   3215 .PP 
   3216 On BSD style systems, daemons are booted directly from \f(CW/etc/rc\fP and
   3217 related scripts\&. Incase you have a file \f(CW/etc/rc\&.local\fP, edit it,
   3218 and add the statement:
   3219 .PP 
   3220 .nf 
   3221 /usr/local/bin/crossroads start
   3222 .fi 
   3223 
   3224 .PP 
   3225 If your BSD system lacks \f(CW/etc/rc\&.local\fP, then you may need to start
   3226 Crossroads from \f(CW/etc/rc\fP\&. Your mileage may vary\&.
   3227 .PP