File: lbcd.8.in

package info (click to toggle)
lbcd 3.5.2-4
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 1,708 kB
  • sloc: ansic: 11,073; sh: 1,816; perl: 503; makefile: 165
file content (460 lines) | stat: -rw-r--r-- 19,620 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
.\" Automatically generated by Pod::Man 2.28 (Pod::Simple 3.28)
.\"
.\" Standard preamble:
.\" ========================================================================
.de Sp \" Vertical space (when we can't use .PP)
.if t .sp .5v
.if n .sp
..
.de Vb \" Begin verbatim text
.ft CW
.nf
.ne \\$1
..
.de Ve \" End verbatim text
.ft R
.fi
..
.\" Set up some character translations and predefined strings.  \*(-- will
.\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left
.\" double quote, and \*(R" will give a right double quote.  \*(C+ will
.\" give a nicer C++.  Capital omega is used to do unbreakable dashes and
.\" therefore won't be available.  \*(C` and \*(C' expand to `' in nroff,
.\" nothing in troff, for use with C<>.
.tr \(*W-
.ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p'
.ie n \{\
.    ds -- \(*W-
.    ds PI pi
.    if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch
.    if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\"  diablo 12 pitch
.    ds L" ""
.    ds R" ""
.    ds C` ""
.    ds C' ""
'br\}
.el\{\
.    ds -- \|\(em\|
.    ds PI \(*p
.    ds L" ``
.    ds R" ''
.    ds C`
.    ds C'
'br\}
.\"
.\" Escape single quotes in literal strings from groff's Unicode transform.
.ie \n(.g .ds Aq \(aq
.el       .ds Aq '
.\"
.\" If the F register is turned on, we'll generate index entries on stderr for
.\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index
.\" entries marked with X<> in POD.  Of course, you'll have to process the
.\" output yourself in some meaningful fashion.
.\"
.\" Avoid warning from groff about undefined register 'F'.
.de IX
..
.nr rF 0
.if \n(.g .if rF .nr rF 1
.if (\n(rF:(\n(.g==0)) \{
.    if \nF \{
.        de IX
.        tm Index:\\$1\t\\n%\t"\\$2"
..
.        if !\nF==2 \{
.            nr % 0
.            nr F 2
.        \}
.    \}
.\}
.rr rF
.\"
.\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2).
.\" Fear.  Run.  Save yourself.  No user-serviceable parts.
.    \" fudge factors for nroff and troff
.if n \{\
.    ds #H 0
.    ds #V .8m
.    ds #F .3m
.    ds #[ \f1
.    ds #] \fP
.\}
.if t \{\
.    ds #H ((1u-(\\\\n(.fu%2u))*.13m)
.    ds #V .6m
.    ds #F 0
.    ds #[ \&
.    ds #] \&
.\}
.    \" simple accents for nroff and troff
.if n \{\
.    ds ' \&
.    ds ` \&
.    ds ^ \&
.    ds , \&
.    ds ~ ~
.    ds /
.\}
.if t \{\
.    ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u"
.    ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u'
.    ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u'
.    ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u'
.    ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u'
.    ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u'
.\}
.    \" troff and (daisy-wheel) nroff accents
.ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V'
.ds 8 \h'\*(#H'\(*b\h'-\*(#H'
.ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#]
.ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H'
.ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u'
.ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#]
.ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#]
.ds ae a\h'-(\w'a'u*4/10)'e
.ds Ae A\h'-(\w'A'u*4/10)'E
.    \" corrections for vroff
.if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u'
.if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u'
.    \" for low resolution devices (crt and lpr)
.if \n(.H>23 .if \n(.V>19 \
\{\
.    ds : e
.    ds 8 ss
.    ds o a
.    ds d- d\h'-1'\(ga
.    ds D- D\h'-1'\(hy
.    ds th \o'bp'
.    ds Th \o'LP'
.    ds ae ae
.    ds Ae AE
.\}
.rm #[ #] #H #V #F C
.\" ========================================================================
.\"
.IX Title "LBCD 8"
.TH LBCD 8 "2015-04-26" "3.5.2" "lbcd"
.\" For nroff, turn off justification.  Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
.nh
.SH "NAME"
lbcd \- Report system load for remote load balancing
.SH "SYNOPSIS"
.IX Header "SYNOPSIS"
\&\fBlbcd\fR [\fB\-dfhlRtZ\fR] [\fB\-a\fR\ \fIallowed-service\fR\ [\fB\-a\fR\ \fIallowed-service\fR]]
    [\fB\-b\fR\ \fIbind-address\fR\ [\fB\-b\fR\ \fIbind-address\fR]] [\fB\-c\fR\ \fIcommand\fR]
    [\fB\-P\fR\ \fIfile\fR] [\fB\-p\fR\ \fIport\fR] [\fB\-T\fR\ \fIseconds\fR]
    [\fB\-w\fR\ \fIweight\fR]
.PP
\&\fBlbcd\fR \fB\-t\fR [v2] [\fIservice\fR ...]
.SH "DESCRIPTION"
.IX Header "DESCRIPTION"
\&\fBlbcd\fR runs as a daemon and reports various system utilization
information and optionally service status information via a \s-1UDP\s0 network
protocol.  It is designed to run on the client systems of a remote load
balancing system, such as the DNS-based \fBlbnamed\fR load balancer.
.PP
\&\fBlbcd\fR supports two different query protocols, version two and version
three.  (Currently, \fBlbnamed\fR only supports version two queries.)  Either
will return the current time according to that system, the time of the
last system boot, the time the information about logged in users last
changed, the load averages (one, five, and fifteen minute), the total and
unique logged in users, whether a user is logged in on console, percentage
full of the system \fI/tmp\fR directory is full, and percentage full of the
system \fI/var/tmp\fR directory.  (See, however, the note below about how
some of this data is replaced with calculated weights for version two
responses.)  The version three protocol can also return weight and
increment information about a set of services.
.PP
The service information is based around a model that returns a weight
(indicating the current utilization of the box \*(-- the higher, the busier)
and an increment (an estimate of how much the utilization will increase
for each additional connection directed to this box) which defaults to
one.  The intent is for the load balancer to query the system
periodically, using the returned weight as the system load, and to
estimate the system load between queries of \fBlbcd\fR as the last returned
weight plus the last returned increment times the number of connections
directed to that system.
.PP
By default, only one service is returned.  That default service weight is
calculated as follows:
.PP
.Vb 2
\&    (<uniq\-users> * 100 + 300 * <one\-minute\-load>
\&        + (<total\-users> \- <unique\-users>) * 20) * <tmp\-penalty>
.Ve
.PP
where <tmp\-penalty> is a multiplier applied for the most full of \fI/tmp\fR
and \fI/var/tmp\fR.  <tmp\-penalty> will be 1 if both are less than 90% full
and will range between 2 for 90\-93% full up to 32 for 100% full.  If
\&\fI/tmp\fR or \fI/var/tmp\fR are completely full, the maximum possible weight
will be returned.  Different algorithms for determining the weight can be
used instead; see the \fB\-w\fR option.
.PP
If you want to use a simple load average instead, pass the \fB\-S\fR option to
\&\fBlbcd\fR and then the load service will use only the one-minute load.  If
you want every system running \fBlbcd\fR to return the same load, use the
\&\fB\-R\fR option.
.PP
If the file \fI\f(CI@sysconfdir\fI@/nolbcd\fR exists, \fBlbcd\fR will force the weight
of the default service to the maximum value regardless of the normal
service calculation.  This allows one to effectively remove a host from a
load-balanced pool by touching a file without having to stop the \fBlbcd\fR
daemon.
.PP
Since \fBlbnamed\fR calculates the weight from the one minute load and the
number of logged-in users and currently only supports version two, \fBlbcd\fR
will replace the one-minute load with the weight of the primary service
when responding to a version two query and will set all of the user
numbers to zero unless \fB\-S\fR was given.  If \fB\-S\fR was given, the values
returned will be left alone.  (This means that \fB\-S\fR will override \fB\-R\fR
for version two queries, since \fB\-R\fR is equivalent to specifying a service
of \f(CW\*(C`rr\*(C'\fR.)
.PP
\&\fBlbcd\fR responds to any \s-1UDP\s0 packets on port 4330 (or the port given with
the \fB\-p\fR option).  It has no built-in security, so if you do not want to
disclose the above information to random systems on the Internet, you will
want to limit access to this port using iptables, firewall rules, or other
similar measures.
.PP
By default, \fBlbcd\fR listens on all addresses and responds on whatever
address the kernel picks for outgoing packets.  \fBlbnamed\fR sends out all
of its packets and then waits for replies and uses the source address of
the reply packet to associate that reply with one of the queried hosts.
This means that if \fBlbnamed\fR is not configured to query the same address
as the kernel picks for \fBlbcd\fR to respond on, the response may be ignored
and the host considered down.  To work around this, use the \fB\-b\fR flag on
hosts with multiple interfaces to ensure that replies go out on the
interface being queried.  If a host has multiple \s-1IP\s0 addresses that will be
queried, run multiple instances of \fBlbcd\fR, one for each interface.
.SH "OPTIONS"
.IX Header "OPTIONS"
.IP "\fB\-a\fR \fIallowed-service\fR" 4
.IX Item "-a allowed-service"
The version 3 lbcd protocol allows the client to request weight
information for a specific protocol.  To prevent clients from getting
information about (and causing \fBlbcd\fR to probe) services that shouldn't
be exposed over protocol, only services specified with the \fB\-a\fR option
are allowed.  This option may be given multiple times to allow multiple
services to be queried.  The service specified with \fB\-w\fR, if any, is
always allowed, as is the \f(CW\*(C`default\*(C'\fR service.
.Sp
For a list of the supported services, and therefore the allowed values
for \fIallowed-service\fR, see the \fB\-w\fR option.
.Sp
Client queries are compared exactly against the \fIallowed-service\fR values,
including any port information after a colon, so all service values that
should be queryable must be listed using this option.
.IP "\fB\-b\fR \fIbind-address\fR" 4
.IX Item "-b bind-address"
By default, \fBlbcd\fR binds to all available addresses.  If this option is
given, \fBlbcd\fR binds only to the specified address and will only answer
\&\s-1UDP\s0 queries to that address.  This option may be given multiple times to
bind to multiple addresses.  \fIbind-address\fR must be an \s-1IP\s0 address (either
IPv4 or IPv6), not a hostname.
.Sp
This option is ignored if \fBlbcd\fR is passed already open sockets via the
systemd socket activation protocol.  In that case, the bind addresses of
the sockets should be controlled via the systemd configuration.
.IP "\fB\-c\fR \fIcommand\fR" 4
.IX Item "-c command"
Obtain the service weight and increment by running an external command.
This command should print to standard output one line containing two
integer numbers, separated by whitespace.  The first number is taken to be
the weight and the second number is taken to be the increment.  (As
mentioned above, when responding to version two protocol queries, the
weight is returned as the one-minute load average.)
.IP "\fB\-d\fR" 4
.IX Item "-d"
Run in the foreground (the same as with \fB\-f\fR), send informational
messages to standard output instead of syslog, and send errors to standard
error instead of syslog.  This is intended for debugging.
.IP "\fB\-f\fR" 4
.IX Item "-f"
Run in the foreground, meaning don't fork and don't detach from the
controlling terminal.  This allows \fBlbcd\fR to be run more simply via
modern init systems such as upstart or systemd and work properly with
process supervisors such as daemontools or runit.
.IP "\fB\-h\fR" 4
.IX Item "-h"
Print out usage information and exit.
.IP "\fB\-l\fR" 4
.IX Item "-l"
Log every received request to syslog (or to standard output if \fB\-d\fR was
given).  The requests will be logged with the \s-1LOG_DAEMON\s0 facility and the
\&\s-1LOG_INFO\s0 priority.
.IP "\fB\-P\fR \fIfile\fR" 4
.IX Item "-P file"
Store the \s-1PID\s0 of the running daemon in \fIfile\fR.  \fIfile\fR will be deleted
when \fBlbcd\fR exits normally (via a \s-1SIGTERM\s0 or \s-1SIGINT\s0 signal).
.IP "\fB\-p\fR \fIport\fR" 4
.IX Item "-p port"
Listen on \fIport\fR rather than the default of 4330.
.Sp
This option is ignored if \fBlbcd\fR is passed already open sockets via the
systemd socket activation protocol.  In that case, the listening port
should be controlled via the systemd configuration.
.IP "\fB\-R\fR" 4
.IX Item "-R"
Use round-robin as the service.  This will always return a weight of one
and an increment of one.  It is equivalent to \f(CW\*(C`\-w rr\*(C'\fR.  For version two
responses, it will always return a one-minute load of one regardless of
the actual load average of the system (unless \fB\-S\fR is used).
.IP "\fB\-S\fR" 4
.IX Item "-S"
When answering version two queries, do not attempt to adjust for
\&\fBlbnamed\fR's logic and force it to use the service weight.  Instead,
report the load averages and number of logged in users accurately.  This
means that version two responses will not contain any information derived
from custom services or weight settings and the \fB\-c\fR, \fB\-w\fR, and \fB\-R\fR
options will be ignored for version two responses.
.IP "\fB\-T\fR \fIseconds\fR" 4
.IX Item "-T seconds"
Use a timeout of \fIseconds\fR when doing service probes (including running a
command with \fB\-c\fR).  The default is five seconds.
.IP "\fB\-t\fR" 4
.IX Item "-t"
Test mode.  When run with the \fB\-t\fR flag, \fBlbcd\fR will do all the checks
that it would do when receiving a query packet, print out the results in a
human-readable format to standard output, and then exit.
.Sp
When run with this option, the remaining command-line arguments are taken
as services to probe.  The valid service names are the same as the valid
service arguments to the \fB\-w\fR option, with one exception.  If the first
service is the string \f(CW\*(C`v2\*(C'\fR, \fBlbcd\fR will behave as if it received a
protocol version two query packet and will manipulate its reply
information accordingly before printing it out.
.IP "\fB\-w\fR \fIweight\fR" 4
.IX Item "-w weight"
Specify either a service to probe or a weight and increment to always
return.  \fIweight\fR can be a string of the form \fIweight\fR:\fIincrement\fR
where both \fIweight\fR and \fIincrement\fR are numbers, in which case that
weight and increment will always be returned.  Alternately, it can be the
name of a service module, in which case that service will be probed and
its weight will be returned as the service weight (and the one-minute load
with version two queries).
.Sp
The currently supported services are \f(CW\*(C`load\*(C'\fR (the default), \f(CW\*(C`ftp\*(C'\fR,
\&\f(CW\*(C`http\*(C'\fR, \f(CW\*(C`imap\*(C'\fR, \f(CW\*(C`nntp\*(C'\fR, \f(CW\*(C`ntp\*(C'\fR, \f(CW\*(C`pop\*(C'\fR, \f(CW\*(C`smtp\*(C'\fR, \f(CW\*(C`tcp\*(C'\fR, and \f(CW\*(C`rr\*(C'\fR
(round-robin, the same as \fB\-R\fR).  The \f(CW\*(C`http\*(C'\fR and \f(CW\*(C`tcp\*(C'\fR services must be
followed by a colon and a port number.
.Sp
This option only affects the default service.  A version 3 protocol client
can query any of the supported services provided that the service is
listed as allowed, using the \fB\-a\fR flag.  This allows the client to get
weight and increment information for several different services.
.IP "\fB\-Z\fR" 4
.IX Item "-Z"
When \fBlbcd\fR has set up its network socket and is ready to answer
requests, raise \s-1SIGSTOP. \s0 This signals to upstart, when using \f(CW\*(C`expect
stop\*(C'\fR, that the daemon is ready to accept connections, and upstart will
raise \s-1SIGCONT\s0 to allow \fBlbcd\fR to continue.  This option is probably only
useful when using upstart as the init system.
.SH "EXAMPLES"
.IX Header "EXAMPLES"
Run \fBlbcd\fR as a daemon, using the default load service, and writing a
\&\s-1PID\s0 file to \fI/var/run/lbcd.pid\fR:
.PP
.Vb 1
\&    lbcd \-P /var/run/lbcd.pid
.Ve
.PP
Run \fBlbcd\fR in the foreground, and log all client requests via syslog.
This is a typical invocation with systemd, using socket activation.
.PP
.Vb 1
\&    lbcd \-f \-l
.Ve
.PP
The same, but raise \s-1SIGSTOP\s0 after \fBlbcd\fR is ready to answer queries.
This is a typical invocation with upstart.
.PP
.Vb 1
\&    lbcd \-f \-l \-Z
.Ve
.PP
Run \fBlbcd\fR as a daemon, with default behavior, but use round-robin as the
default service.  This will equally balance queries across machines
instead of trying to be sensitive to load.
.PP
.Vb 1
\&    lbcd \-R
.Ve
.PP
Determine the weight of the system based on whether the local \s-1HTTP\s0 port is
responding.  If it isn't, the system will return the maximum weight, which
will cause it to drop out of the pool.
.PP
.Vb 1
\&    lbcd \-w http:80
.Ve
.PP
Run the external program \fI/usr/bin/lb\-slapd\fR to determine the weight.
.PP
.Vb 1
\&    lbcd \-c /usr/bin/ldap\-check
.Ve
.PP
This program should print, to standard output, two numbers separated by a
space.  The first will be the weight and the second will be the load.  In
this case, it does a query against a local \s-1LDAP\s0 search to determine its
health.  (A good approach for \s-1LDAP\s0 slaves would be to check the syncrepl
data to see if the slave is up-to-date.)
.SH "ENVIRONMENT"
.IX Header "ENVIRONMENT"
.IP "\s-1LISTEN_FDS\s0" 4
.IX Item "LISTEN_FDS"
.PD 0
.IP "\s-1LISTEN_PID\s0" 4
.IX Item "LISTEN_PID"
.PD
If these environment variables are set, \fBlbcd\fR will expect to be provided
its listening sockets via the systemd socket activation protocol and will
not attempt to bind its own sockets.  For more details on the protocol,
see \fIdaemon\fR\|(7) and \fIsd_listen_fds\fR\|(3).
.IP "\s-1NOTIFY_SOCKET\s0" 4
.IX Item "NOTIFY_SOCKET"
If this environment variable is set, \fBlbcd\fR will notify the socket named
in this variable when it is ready to accept incoming packets using the
systemd status notification protocol.  For more details, see \fIdaemon\fR\|(7)
and \fIsd_notify\fR\|(3).
.Sp
Note that using socket activation is recommended when running under
systemd, and status notification is not necessary or useful when using
socket activation.
.SH "FILES"
.IX Header "FILES"
.ie n .IP "\fI\fI@sysconfdir\fI@/nolbcd\fR" 4
.el .IP "\fI\f(CI@sysconfdir\fI@/nolbcd\fR" 4
.IX Item "@sysconfdir@/nolbcd"
If this file exists, \fBlbcd\fR will force the weight of the default service
to the maximum possible value regardless of the normal weight calculation.
This allows one to effectively remove a host from a load-balanced pool by
touching a file without having to stop the \fBlbcd\fR daemon.
.IP "\fI/etc/nologin\fR" 4
.IX Item "/etc/nologin"
If this file exists, \fBlbcd\fR will force the weight returned by the default
load algorithm to the maximum possible value.  This will only apply if the
default load algorithm is used; if a different algorithm is used, due to
\&\fB\-R\fR or \fB\-w\fR, no change to the returned weight will be made.
.SH "AUTHORS"
.IX Header "AUTHORS"
Originally written by Roland Schemers and Larry Schwimmer.  Currently
maintained by Russ Allbery <eagle@eyrie.org>.
.SH "COPYRIGHT AND LICENSE"
.IX Header "COPYRIGHT AND LICENSE"
Copyright 1993, 1994, 1996, 1997, 1998, 2000, 2003, 2004, 2005, 2006,
2009, 2012, 2013, 2014 The Board of Trustees of the Leland Stanford Junior
University
.PP
Copying and distribution of this file, with or without modification, are
permitted in any medium without royalty provided the copyright notice and
this notice are preserved.  This file is offered as-is, without any
warranty.
.SH "SEE ALSO"
.IX Header "SEE ALSO"
\&\fIlbcdclient\fR\|(1)
.PP
The current version of this program is available from its web page at
<http://www.eyrie.org/~eagle/software/lbcd/>.