This is ./serveez.info, produced by makeinfo version 4.0 from
serveez.texi.

INFO-DIR-SECTION Serveez - A server framework.
START-INFO-DIR-ENTRY
* Serveez: (serveez).           Serveez Documentation.
END-INFO-DIR-ENTRY


File: serveez.info,  Node: Top,  Next: Introduction,  Prev: (dir),  Up: (dir)

   This file documents the Serveez server framework.

* Menu:

* Introduction::          Introduction to Serveez
* Using Serveez::         Startup and command line options
* Concept::               Conceptual thoughts
* Server::                Server implementation
* Coserver::              Coserver implementation
* Porting issues::        Support of different platforms and operating systems
* Bibliography::          Useful documents we refer to
* License::               GNU General Public License


File: serveez.info,  Node: Introduction,  Next: Using Serveez,  Prev: Top,  Up: Top

Introduction
************

   Serveez is a server framework.  It provides routines and help for
implementing IP based servers (currently TCP, UDP and ICMP).  It is also
possible to use named pipes for all connection oriented protocols.

   We think it is worth the effort because many people need server
functionality within their applications.  However, many people
experience problems with select()- or poll()-loops, and with
non-blocking operations.

   This application demonstrates various aspects of advanced network
programming in a portable manner.  It is known to compile and run on
GNU/Linux systems, as well as on other 32-bit and 64-bit flavours of
Unix and on Microsoft Windows (9x/ME/NT/2000/XP).

   You can use it for implementing your own servers or for
understanding how certain network services and operations work.

   The package includes a number of servers that work already: an HTTP
server, an IRC server, a Gnutella spider and some others.  One of the
highlights is that you can run all protocols on the same port.  The
application itself is single threaded but it uses helper processes for
concurrent name resolution and ident lookups.


File: serveez.info,  Node: Using Serveez,  Next: Concept,  Prev: Introduction,  Up: Top

Using Serveez
*************

   We know, you usually don't read the documentation. Who does. But
please, read at the very least this chapter. It contains information on
the basic concepts. Larger parts of the manual can be used as a
reference manual for the various servers.

Building and installing
=======================

Rebuild the package from the sources
------------------------------------

   You can skip this section if you are familiar with the GNU'ish way of
configuring, compiling and installing a GNU package.

Getting the source
..................

   Serveez can be found on `http://ftp.gnu.org/gnu/serveez/', on one of
the mirrors (`http://www.gnu.org/prep/ftp.html') or at its original
location `http://www.textsure.net/~ela/download/'. At this location you
will also find the RPM package mentioned in the next section.

Requirements
............

   Serveez needs GNU Guile (Ubiquitous Intelligent Language for
Extensions).  The current version of Serveez is known to work with
Guile 1.3 and later.  Guile can be downloaded at
`http://ftp.gnu.org/gnu/guile/'.

Installation
............

Unpack the distribution tarball:
    sleepless ~> gzip -cd serveez-0.1.4.tar.gz | tar xvf -

Change into the source directory:
    sleepless ~> cd serveez-0.1.4

Configure the source package for your system:
  We recommend to use `--enable-opt' unless you have a good reason not
  to do so. It follows a complete list of the `configure' script
  options.  The list of known options can the obtained via `./configure
  --help'.

 `--enable-warn'
    With this option you enable the detection of various compiler
    warning switches.  Most guessed options come from GCC.

 `--enable-opt'
    When enabling this feature the configure script tries some of the
    commonly known compiler optimization switches.

 `--with-opt=FLAGS'
    You can pass here a comma separated list of additional compiler
    flags which will be tested.  This feature is only active if you
    specified the above `--enable-opt' switch.

 `--enable-ppro'
    If you want to compile for the i686 target try this option.

 `--enable-486'
    Compiler optimizations for the i486 target of GCC.  If you passed
    `--enable-ppro' and this option could be used, then the i486 option
    will be silently dropped.

 `--enable-debug'
    All of the debug messages (debug: some annoying crap text) can be
    suppressed by setting the debug level (-v).  If you do not want
    these messages built in at all then disable this feature.

 `--enable-control-proto'
    If you enable this feature the control protocol will be supported
    by Serveez.  This protocol is for remote control of the server.

 `--enable-irc-proto'
    Enabling this feature tells the software package to support the IRC
    (Internet Relay Chat) protocol.

 `--enable-irc-ts'
    This feature is only available if you enabled the IRC protocol.  If
    you enabled both of them then Serveez will support the so called
    TimeStamp protocol, which is an EFNet extension of the original IRC
    protocol.  In order to connect to EFNet you MUST use this option.

 `--enable-awcs-proto'
    In order to use the Serveez software for the textSure (C) chat
    system you MUST enable this feature.

 `--enable-http-proto'
    When using Serveez as part of the textSure (C) chat system you will
    will have need of an additional web server.  This option makes
    Serveez support a simple HTTP protocol.

 `--enable-flood'
    If you enable this feature Serveez will support a simple built-in
    flood protection.  It is always useful to protect the software from
    flood clients.

 `--with-guile=DIR'
    The DIR argument specifies a Guile installation directory.

 `--with-guile-source=DIR'
    If the user wants to link Serveez against a static Guile core
    library you can pass the DIR argument to specify the location of a
    Guile source distribution which will then be configured and built.

 `--with-mingw=DIR'
    When compiling under M$-Windows the DIR argument specifies the path
    to the extra MinGW32 library and header files.  If you want the
    final executable to use the Cygwin project's cygwin1.dll instead,
    you have to disable this option by passing configure script
    `--without-mingw' or `--with-mingw=no'.

 `--enable-sntp-proto'
    This option enables support for a simple network time protocol
    server.

 `--enable-poll'
    If the target system supports `poll()' and this feature is enabled
    the main file descriptor loop is done via `poll()'.  This helps to
    work around the (g)libc's file descriptor limit.  Otherwise Serveez
    always falls back to the `select()' system call.

 `--enable-sendfile'
    This option enables the use of the `sendfile()' system call.
    Disabling it using `--disable-sendfile' provides a work-around for
    bogus implementations of `sendfile()'.

 `--enable-gnutella'
    If you do *not* want the Gnutella spider client compiled in you
    need to *disable* this option.

 `--enable-crypt'
    This option tells Serveez to process any passwords as crypt()ed.

 `--enable-tunnel'
    If you enable this feature the port forwarder will be included.
    This is useful if you plan to use Serveez as a gateway or firewall
    workaround.

 `--enable-fakeident'
    By enabling this you will get a fake ident server included in the
    binary executable.

 `--enable-guile-server'
    If you enable this feature the user is able to write servers using
    Guile.

 `--enable-passthrough'
    This includes the program passthrough server in the Serveez binary.
    The server provides basic inetd functionality.

 `--enable-iflist'
    If Serveez is unable to detect the correct list of local network
    interfaces (`serveez -i') you can disable this option and setup
    them manually in the configuration file.

 `--enable-heap-count'
    This option depends on `--enable-debug'.  With the debugging option
    disabled there is also no support for heap counters.  The heap
    counters are used to detect memory leaks in Serveez.

    sleepless ~/serveez-0.1.4> sh configure --enable-opt

Now compile the package:
    sleepless ~/serveez-0.1.4> make

Install serveez:
  You must have root privileges if you want to install the package in
  the standard location `/usr/local' or in any location that is only
  writable by root.
    sleepless ~/serveez-0.1.4> make install

   If you have problems building the package out of the box this is due
to GNU libtool's inability to handle dynamic linking in most cases.
That is why we recommend to try to configure the package with
`--disable-shared' and/or the native compiler (if any). When the build
process is not able to link against an existing Guile installation you
can try to use the `--with-guile-source=DIR' configure option.

Installing the RPM package
--------------------------

   The binary RPM distribution `serveez-0.1.4-1.i386.rpm' of Serveez
has been prebuild on a x86 / GNU/Linux 2.4 machine. It is a relocatable
package with its default installation directory in `/opt/serveez'. You
need to ensure root privileges in order to install or remove rpm
packages.

Query information:
    sleepless ~> rpm -qiRl -p serveez-0.1.4-1.i386.rpm

Install the package:
    sleepless ~> rpm -Uvh serveez-0.1.4-1.i386.rpm [ --nodeps ] [ --prefix=/opt/serveez ]
    serveez                     ####################

Uninstall the package:
    sleepless ~> rpm -ev serveez-0.1.4

Installing the Debian package
-----------------------------

   The binary Debian distribution `serveez_0.1.4_i386.deb' of Serveez
has been prebuild on a x86 / GNU/Linux 2.4 machine.  You need to ensure
root privileges in order to install or remove Debian packages.

Query information:
    sleepless ~> dpkg -I serveez_0.1.4_i386.deb
    sleepless ~> dpkg -c serveez_0.1.4_i386.deb

Install the package:
    sleepless ~> dpkg -i serveez_0.1.4_i386.deb

Uninstall the package:
    sleepless ~> dpkg -r serveez

Environment variables
=====================

   When using the serveezopt package or playing around with the dynamic
server module loader of Serveez you can tell the core API of Serveez
(which is the `libserveez.[so|dll]' library) to use an additional load
path to find these server modules. The environment variable
`SERVEEZ_LOAD_PATH' holds this information. You can set it up via:

    on Unices
  sleepless ~> export SERVEEZ_LOAD_PATH=/home/lib:/usr/local/lib
  
    or on Windows
  C:\HOME> set SERVEEZ_LOAD_PATH=C:\HOME\LIB;C:\USR\LOCAL\LIB

Starting Serveez
================

   When Serveez is started it reads its configuration from a file called
`serveez.cfg' in the current directory and runs the server loop
afterwards. Press <^C>  to abort the execution of this program.
Serveez is not interactive and does not automatically detach from the
terminal.

Command line options
====================

`-h, --help'
  Display this help and exit.

`-V, --version'
  Display version information and exit.

`-i, --iflist'
  List local network interfaces and exit.

`-f, --cfg-file=FILENAME'
  File to use as configuration file (serveez.cfg).

`-v, --verbose=LEVEL'
  Set level of logging verbosity.

`-l, --log-file=FILENAME'
  Use `FILENAME' for logging (default is stderr).

`-P, --password=STRING'
  Set the password for control connections.

`-m, --max-sockets=COUNT'
  Set the maximum number of socket descriptors.

`-d, --daemon'
  Start as daemon in background.

`-c, --stdin'
  Use standard input as configuration file.

Configuring Serveez
===================

   As noted above Serveez is configured via a configuration file which
is by default `serveez.cfg' and can be set by passing the `-f' command
line argument.  When you pipe a file into Serveez or pass the `-c'
argument on the command line the input stream will be used as
configuration file no matter whether you passed a `-f' command line
switch or not.

   To make configuring more fun we did not invent yet another
configuration file format.  Instead we use a dialect of the Scheme
programming language called GNU Guile
(`http://www.gnu.org/software/guile/').  There is no need to be worried
if you are not a programmer.  What you have to do is really simple and
this document shows you everything you need to know.  We also provide
many examples.  However there are some simple concepts you have to
understand.  The following paragraphs will explain them.

   The idea of the configuration file is this: Serveez starts, runs the
configuration file (other applications usually just read them and
remember the settings) and finally enters its main loop doing the
things you wanted it to.

   There are three things you have to do in the configuration file.

* Menu:

* Define ports::           Port configuration definition
* Define servers::         Server definition
* Bind servers to ports::  How to bind servers to port configurations


File: serveez.info,  Node: Define ports,  Next: Define servers,  Up: Using Serveez

Define ports
------------

   A `port' (in Serveez) is a transport endpoint. You might know them
from other TCP or UDP server applications. For example: web servers
(HTTP) usually listen on TCP port 80. However, there is more than TCP
ports: we have UDP, ICMP and named pipes each with different options to
set. Every port has a unique name you assign to it. The name of the
port is later used to bind servers to it.

   The following examples show how you setup different types of port
configurations. You start to define such a port using the Guile function
`(define-port!)'. The first argument to this functions specifies the
name of the port configuration. The remaining argument describes the
port in detail.

Port configuration items
........................

   This table describes each configuration item for a port in Serveez.
Note that not each item applies to every kind of port configuration.

`proto (string)'
  This is the main configuration item for a port configuration setting
  up the type of port.  Valid values are `tcp', `udp', `icmp', `raw'
  and `pipe'.  This configuration item decides which of the remaining
  configuration items apply and which do not.

`port (integer in the range 0..65535)'
  The `port' item determines the network port number on which TCP and
  UDP servers will listen.  Thus it does not make sense for ICMP and
  named pipes.  If you pass `0' Serveez will determine a free port in
  the range between 1 and 65535.

`recv (string or associative list)'
  This item describes the receiving (listening) end of a named pipe
  connection, i.e. the filename of a fifo node to which a client can
  connect by opening it for writing.  Both the `recv' and `send' item
  apply to named pipes only.  The value can either be an associative
  list or a simple filename. Using a simple filename leaves additional
  options to use default values. They deal mainly with file permissions
  and are described below.

`send (string or associative list)'
  This item is the sending end of a named pipe connection. It is used to
  send data when the receiving (listening) end has detected a
  connection.  The following table enumerates the additional options
  you can setup if you pass an associative list and not a simple
  filename.

 `name (string)'
    The filename of the named pipe.  On Windows systems you can also
    specify the hostname on which the pipe should be created in the
    format `\\hostname\pipe\name'.  By default (if you leave the leading
    `\\hostname\pipe\' part) the pipe will be created on
    `\\.\pipe\name' which refers to a pipe on the local machine.

 `permission (octal integer)'
    This specifies the file permissions a named pipe should be created
    with.  The given number is interpreted in a Unix'ish style (e.g.
    `#o0666' is a permission field for reading and writing for the
    creating user, all users in the same group and all other users).

 `user (string)'
    The file owner (username) of the named pipe in textual form.

 `group (string)'
    The file owner group (groupname) of the named pipe in textual form.
    If this item is left it defaults to the file owner's primary group.

 `uid (integer)'
    The file owner of the named pipe as a user id.  You are meant to
    specify either the `uid' item or the `user' item.  Serveez will
    complain about conflicting values.

 `gid (integer)'
    The file owner group of the named pipe as a group id.  This item
    defaults to the file owner's primary group id.  You are meant to
    specify either the `gid' item or the `group' item.  Serveez will
    croak about conflicting values.

`ipaddr (string)'
  This configuration item specifies the IP address (either in dotted
  decimal form e.g. `192.168.2.1' or as a device description which can
  be obtained via `serveez -i') to which a server is bound to.  The `*'
  keyword for all known IP addresses and the `any' keyword for any IP
  address are also valid values.  The default value is `*'.  The
  configuration item applies to network ports (TCP, UDP and ICMP) only.

`device (string)'
  The `device' configuration item also refers to the IP address a server
  can be bound to.  It overrides the `ipaddr' item.  Valid values are
  network device descriptions (probably no aliases and no loopback
  devices).  It applies to network ports (TCP, UDP and ICMP) only.

  A note on device bindings:  Device bindings are based on the
  `SO_BINDTODEVICE' socket layer option.  This option is not available
  on all systems.  We only tested it on GNU/Linux (2.2.18 and 2.4.17 as
  of this writing).  Device bindings are very restrictive: only root
  can do it and only physical devices are possible.  The loopback
  device cannot be used and no interface alias (i.e. `eth0:0').  A
  device binding can only be reached from the physical outside but it
  includes all aliases for the device.  So if you bind to device `eth0'
  even `eth0:0' (and all other aliases) are used.  The connection has
  to be made from a remote machine.  The advantage of this kind of
  binding is that it survives changes of IP addresses.  This is tested
  for ethernet networks (i.e. eth*) and isdn dialups (i.e. ippp*).  It
  does not work for modem dialups (i.e. ppp*) (at least for Stefan's
  PCMCIA modem).  The problem seems to be the dialup logic actually
  destroying ppp*.  Other opinions are welcome.  Device bindings always
  win: If you bind to `*' (or an individual IP address) and to the
  corresponding device, connections are made with the device binding.
  The order of the `(bind-server!)' statements do not matter.  This
  feature is not thoroughly tested.

`backlog (integer)'
  The `backlog' parameter defines the maximum length the queue of
  pending connections may grow to.  If a connection request arrives
  with the queue full the client may receive an error.  This parameter
  applies to TCP ports only.

`type (integer in the range 0..255)'
  This item applies to ICMP ports only.  It defines the message type
  identifier used to send ICMP packets (e.g. `8' is an echo message
  i.e. PING).

`send-buffer-size (integer)'
  The `send-buffer-size' configuration item defines the maximum number
  of bytes the send queue of a client is allowed to grow to.  The item
  influences the "send buffer overrun error condition".  For packet
  oriented protocols (UDP and ICMP) you need to specify at least the
  maximum number of bytes a single packets can have.  For UDP and ICMP
  this is 64 KByte.  The value specified here is an initial value. It
  is used unless the server bound to this port changes it.

`recv-buffer-size (integer)'
  The `recv-buffer-size' configuration item defines the maximum number
  of bytes the receive queue of a client is allowed to grow to.  The
  item influences the "receive buffer underrun error condition".  The
  value specified here is an initial value. It is used unless the server
  bound to this port changes it.

`connect-frequency (integer)'
  This item determines the maximum number of connections per second the
  port will accept.  It is a kind of "hammer protection".  The item is
  evaluated for each remote client machine separately.  It applies to
  TCP ports.

`allow (list of strings)'
  Both the `allow' and `deny' lists are lists of IP addresses in dotted
  decimal form (e.g. `192.168.2.1'). The `allow' list defines the
  remote machines which are allowed to connect to the port.  It applies
  to TCP ports.

`deny (list of strings)'
  The `deny' list defines the remote machines which are not allowed to
  connect to the port.  Each connection from one of these IP addresses
  will be refused and shut down immediately.  It applies to TCP ports.

TCP port definition
...................

   Definition of a TCP port configuration with the name "foo-tcp-port".
The enhanced settings are all optional including the IPADDR property
which defaults to `*'. The IPADDR item can contain any form of a dotted
decimal internet address, a `*', `any' or an interface description
which you can obtain by running `serveez -i'.

  (define-port! 'foo-tcp-port '(
      ;; usual settings
      (proto  . tcp)              ;; protocol is tcp
      (port   . 42421)            ;; network port 42421
      (ipaddr . *)                ;; bind to all known interfaces
      (device . eth0)             ;; bind to network card
  
      ;; enhanced settings
      (backlog           . 5)     ;; enqueue max. 5 connections
      (connect-frequency . 1)     ;; allow 1 connect per second
      (send-buffer-size  . 1024)  ;; initial send buffer size in bytes
      (recv-buffer-size  . 1024)  ;; initial receive buffer size in bytes
  
      ;; allow connections from these ip addresses
      (allow             . (127.0.0.1 127.0.0.2))
  
      ;; refuse connections from this ip address
      (deny              . (192.168.2.7))
    ))

Pipe port definition
....................

   Definition of a pipe port configuration with the name
"foo-pipe-port". When bound to a server it creates the receiving end
and listens on that. If some client accesses this named pipe the server
opens the sending end which the client has to open for reading
previously.

   The only mandatory item is the file name of each pipe. If you want to
specify a user creating the named pipe (file ownership) use either the
"user" or the "uid" setting. Same goes for "group" and "gid".

  (define-port! 'foo-pipe-port `(
      (proto . pipe)                   ;; protocol is named pipe
  
      ;; specify the receiving endpoint
      (recv . ((name . ".foo-recv")    ;; name of the pipe
               (permissions . #o0666)  ;; create it with these permissions
               (user . "calvin")       ;; as user "calvin"
               (uid . 50)              ;; with the user id 50
               (group . "heros")       ;; which is in the group "heros"
               (gid . 100)))           ;; with the group id 100
  
      ;; specify the sending endpoint
      (send . ((name . ".foo-send")
               (permissions . #o0666)
               (user . "hobbes")
               (uid . 51)
               (group . "stuffed")
               (gid . 101)))
     ))

ICMP port definition
....................

   Define an ICMP port configuration which will accept connections from
the network interface "127.0.0.1" only and communicates via the message
type 8 as described in the *Note Tunnel Server:: chapter. The name of
this port configuration is "foo-icmp-port". When you are going to bind
some server to this kind of port you have to ensure root (or
Administrator under Windows) privileges.

  (define-port! 'foo-icmp-port '((proto  . icmp)
                                 (ipaddr . 127.0.0.1)
                                 (type   . 8)))

UDP port definition
...................

   Simple definition of a UDP port configuration with the name
"foo-udp-port".

  (define-port! 'foo-udp-port `((proto . udp)
                                (port  . 27952)))


File: serveez.info,  Node: Define servers,  Next: Bind servers to ports,  Prev: Define ports,  Up: Using Serveez

Define servers
--------------

   A `server' (in Serveez) is a snippet of code that implements some
protocol. There are many servers built into Serveez but you can
implement your own, too. For example we provide a webserver
implementing the Hypertext Transfer Protocol (HTTP). Each server has a
different set of options you can change. You can have many instances of
every server, each with a different set of options. For example: You
can create a webserver on TCP port 42420 publishing the Serveez
documentation and also have another webserver on a different port
publishing something else. Every server has a unique name you assign to
it. The name of the server is later used to bind it to a port.

   The following example instantiates a server with the short name
"foo". Each server in Serveez has got a short name. *Note Existing
servers::, for the details. This example demonstrates everything which
is possible in server configurations. You start a definition of a
server with the guile function `(define-server!)'. The following
argument specifies the name of the server instance (in this case
"foo-server") which starts with the short name. The second argument
describes the server in detail. Each configuration item is setup with a
`(key . value)' pair where "key" is the name of the configuration item
and "value" is the value which depends on the type of the item. *Note
Configuring servers::, for a detailed description of each type of value.

  (define-server! 'foo-server '(
      (bar . 100)                             ;; number
      (reply . "Booo")                        ;; character string
      (messages .                             ;; list of strings
        ("Welcome to the foo test server."
         "This one echos your lines."))
      (ports . (5 6 7 8 9))                   ;; list of numbers
      (port . foo-tcp-port)                   ;; a port configuration
      (assoc . (( "GNU" . "great" )           ;; associative list
                ( "Tree" . "tall" )))
      (truth . #f)                            ;; boolean value
    ))

   Serveez provides a number of server types. Each of them has a short
name.  The name of the server instance has to begin with this short
name followed by a dash (-). You can append any suffix then. In the
example above "foo" is the short name and "foo-server" the name of the
server instance.


File: serveez.info,  Node: Bind servers to ports,  Prev: Define servers,  Up: Using Serveez

Bind servers to ports
---------------------

   Finally you can bind servers to ports. When you do so the server you
created listens on the port, accepts connections and serves clients. It
does so as soon as Serveez enters its main loop right after running the
configuration file. Serveez won't stop until you interrupt it (e.g. by
pressing <^C> in the terminal you started it in).

   This example binds the server "foo-server" (s.a.) to the port
"foo-tcp-port" which was described above. Therefore you need to call
the guile function `(bind-server!)' which takes two arguments
specifying the name of a port configuration and a server instance. Both
need to be defined before you can write this statement.

  (bind-server! 'foo-tcp-port 'foo-server)

   One of the main features of Serveez is that you can bind multiple
servers to the same port. This for example useful to pass braindead
firewall configurations or proxy servers. It is also possible to bind
servers to ports they are actually not designed for. This might be used
for debugging servers or other funny things (again, think about the
firewall). This is the point we have to warn you: Some protocols cannot
share the same port (e.g. the tunnel server) and some protocols simply
won't work on 'wrong' ports. Additionally, you will not get error
messages when that happens. The server just will not work then.

Additional configuration possibilities
--------------------------------------

   The three functions `(define-port!)', `(define-server!)' and
`(bind-server!)' return `#t' on success and `#f' on failure.  For your
convenience we provide some more Guile functions.  Some of these are
based upon the above.  You will find the additional functions in the
file `serveez.scm'.  In order to include this convenience functionality
you can `(primitive-load "serveez.scm")' at the top of the
configuration file.

`(interface-add! . interface)'
  Add one more network interface to the list of known interfaces. You
  can get the list of known interfaces by running `serveez -i'. The
  INTERFACE argument must be in dotted decimal form (e.g. 127.0.0.1).
  Serveez provides this function for systems where it is unable to
  detect the list of network interface automatically.

`(loadpath-add! . path)'
  Extends the load path for server modules by the path name PATH.

`(bind-servers! . args)'
  This function is based upon `(bind-server!)'. It takes a list of port
  configurations and servers and binds each to another.

`(bind-tcp-port-range! from to . servers)'
  Bind the list of SERVERS to simple TCP port configurations whose
  network ports range between FROM and TO both inclusive.

`(bind-udp-port-range! from to . servers)'
  Bind the list of SERVERS to simple UDP port configurations whose
  network ports range between FROM and TO both inclusive.

`(serveez-verbosity verbosity)'
  Set the core library's logging verbosity to the VERBOSITY level.
  Lesser values mean fewer logging messages. This settings gets
  overridden by command line.

`(serveez-maxsockets max)'
  Set the number of maximum socket descriptors (number of concurrent
  connections). When passing Serveez the -m command line argument this
  setting gets overridden, too.

`(serveez-passwd password)'
  Set the PASSWORD for the control protocol.

   We now have a closer look at the internals of Serveez. If you are
not interested in that have a look at the existing servers (*Note
Existing servers::.).


File: serveez.info,  Node: Concept,  Next: Server,  Prev: Using Serveez,  Up: Top

Concept
*******

Overall concept
===============

   The primary functionality Serveez provides is a framework for
Internet services.  It can act as a kind of server collection and may
even replace super-servers such as the inetd daemon.

   Its key features and benefits are:

* support for packet and connection oriented protocols
  Serveez currently supports two server types.  TCP and named pipe
  servers are connection oriented servers.  This type of server accepts
  a client's connection request and communicates with it using a
  dedicated connection.  The format of the incoming and outgoing data
  streams are irrelevant to Serveez.  Packet oriented servers (like UDP
  and ICMP) receive data packets and respond to the sender with data
  packets.  A server in Serveez can detect whether it is bound to a
  packet or connection oriented port configuration and thus can act as
  the expected type.

* server and client functionality
  Besides a wide variety of server capabilities, Serveez also contains
  some client functionality.  This may be necessary when a server is
  meant to establish a connection to another server in response to an
  incoming request.  For example, imagine a protocol where a client
  tells the server "Let me be the server.  Please connect to this HOST
  at this PORT.".  You are also able to implement pure clients.

* platform portability
  When writing this software the authors were always mindful of platform
  portability.  Serveez compiles and runs on various Unix platforms as
  well as on Windows systems.  *Note Porting issues::, for details.
  Most of the routines in the core library can be used without regard
  to the platform on which you are programming or the details of its
  underlying system calls.  Exceptions are noted in the documentation.
  Platform portability also means that the server code you write will
  run on other systems, too.

* powerful configuration capabilities
  Server configuration has always been a complicated but very important
  issue.  When Serveez starts up it runs the configuration file using
  the programming language Guile.  In contradiction, other (server)
  applications just read their configuration files and remember the
  settings in it.  This makes them powerful enough to adapt the Serveez
  settings dynamically.  Using the Guile interpreter also means that you
  can split your configuration into separate files and load these,
  perhaps conditionally, from the main configuration file.

* easy server implementation
  Serveez is a server framework.  When implementing a new server the
  programmer need pay little or no attention to the networking code but
  is free direct his attention to the protocol the server is meant to
  support.  That protocol may be an established one such as HTTP, or may
  be a custom protocol fitting the specific application's requirements.
  The *Note Writing servers:: section describes this process in detail.

* code reusability
  The Serveez package comes along with a core library (depending on the
  system this is a static library, shared library or a DLL) and its API
  which contains most of the functionality necessary to write an
  Internet server.  Most probably, a programmer can also use the
  library for other (network programming related) purposes.

* server instantiation and network port sharing
  Once you have written a protocol server and integrated into Serveez's
  concept of servers the user can instantiate (multiply) the server.  At
  the first glimpse this sounds silly, but with different server
  configurations it does not.  If, for example, an administrator wishes
  to run multiple HTTP servers with different document roots, Serveez
  will handle them all in a single process.  Also if the same
  administrator wants to run a HTTP server and some other server on the
  same network port this is possible with Serveez.  You can run a
  single server on different network ports, too.

I/O Strategy
============

   Serveez's I/O strategy is the traditional `select()' method.  It is
serving many clients in a single server thread.  This is done by setting
all network handles to non-blocking mode.  We then use `select()' to
tell which network handles have data waiting.  This is the traditional
Unix style multiplexing.

   An important bottleneck in this method is that a `read()' or
`sendfile()' from disk blocks if the data is not in core at the moment.
Setting non-blocking mode on a disk file handle has no effect.  The
same thing applies to memory-mapped disk files.  The first time a
server needs disk I/O, its process blocks, all clients have to wait, and
raw non-threaded performance may go to waste.

   Unfortunately, `select()' is limited to the number of `FD_SETSIZE'
handles.  This limit is compiled into the standard library, user
programs and sometimes the kernel.  Nevertheless, Serveez is able to
serve about one thousand and more clients on GNU/Linux, a hundred on
Win95 and more on later Windows systems.

   We chose this method anyway because it seems to be the most portable.

   An alternative method to multiplex client network connections is
`poll()'. It is automatically used when `configure' finds `poll()' to
be available. This will work around the builtin (g)libc's `select()'
file descriptor limit.

Limits on open filehandles
--------------------------

`Any Unix'
  The limits set by `ulimit()' or `setrlimit()'.

`Solaris'
  See the Solaris FAQ, question 3.45.

`FreeBSD'
  Use sysctl -w kern.maxfiles=nnnn to raise limit.

`GNU/Linux'
  See Bodo Bauer's /proc documentation.  On current 2.2.x kernels,
    echo 32768 > /proc/sys/fs/file-max
  increases the system limit on open files, and
    ulimit -n 32768
  increases the current process' limit.  We verified that a process on
  Linux kernel 2.2.5 (plus patches) can open at least 31000 file
  descriptors this way.  It has also been verified that a process on
  2.2.12 can open at least 90000 file descriptors this way (with
  appropriate limits).  The upper bound seems to be available memory.

`Windows 9x/ME'
  On Win9x machines, there is quite a low limit imposed by the kernel:
  100 connections system wide (!).  You can increase this limit by
  editing the registry key
  HKLM\System\CurrentControlSet\Services\VxD\MSTCP\MaxConnections.  On
  Windows 95, the key is a DWORD; on Windows 98, it's a string.  We
  have seen some reports of instability when this value is increased to
  more than a few times its default value.

`Windows NT/2000'
  More than 2000 connections tested.  It seems like the limit is due to
  available physical memory.

Alternatives to Serveez's I/O strategy
======================================

   One of the problems with the traditional `select()' method with
non-blocking file descriptors occurs when passing a large number of
descriptors to the `select()' system call.  The server loop then goes
through all the descriptors, decides which has pending data, then reads
and handles this data.  For a large number of connections (say, 90000)
this results in temporary CPU load peaks even if there is no network
traffic.

   Along with this behaviour comes the problem of "starving"
connections.  Connections which reside at the beginning of the
`select()' set are processed immediately while those at the end are
processed significantly later and may possibly die because of buffer
overruns.  This is the reason why Serveez features priority connection:
it serves listening sockets first and rolls the order of the remaining
connections.  In this way, non-priority connections are handled in a
"round robin" fashion.

   Other server implementations solve these problems differently.  Some
start a new process for each connection (fully-threaded server) or split
the `select()' set into pieces and let different processes handle them
(threaded server).  This method shifts the priority scheduling to the
underlying operating system.  Another method is the use of asynchronous
I/O based upon signals where the server process receives a signal when
data arrives for a connection.  The signal handler queues these events
in order of arrival and the main server loop continuously processes
this queue.


File: serveez.info,  Node: Server,  Next: Coserver,  Prev: Concept,  Up: Top

Server
******

* Menu:

* Introduction to servers::     Protocol servers in Serveez
* Writing servers::             How to write Internet protocol servers
* Configuring servers::         How do I configure an existing server ?
* Existing servers::            Which kind of servers do we have already ?


File: serveez.info,  Node: Introduction to servers,  Next: Writing servers,  Prev: Server,  Up: Server

Introduction to servers
=======================

   Serveez is a kind of server server. It allows different protocol
servers to listen on various TCP/UDP ports, on ICMP sockets and on named
pipes. Servers are instantiated with a certain configuration. It is
possible to run multiple different servers on the same port.

   This chapter covers all questions about how to write your own
Internet protocol server with this package. Most of the common tasks of
such a server have got a generic solution (default routines) which
could be "overridden" by your own routines. There are some examples
within this package. They are showing the possibilities with this
package and how to implement servers.

   The `foo' server does not do anything at all and is of no actual use
but could be a basis for a new protocol server. We are now going to
describe how this specific server works. Eventually the reader might
get an impression of what is going on.

   For better understanding the text below we will use the following
terminology:
server definition
  A server definition is a `svz_servertype_t' structure which contains
  server specific members like its name, different callbacks, a single
  default configuration and a list of configuration items which
  determines what can be configured.

server configuration
  A server configuration can be any kind of structure. The default
  server configuration must be specified within the server definition
  (see above).  When instantiating a server (which is done via the
  configuration file) the configuration items specified in the server
  definition get processed and are put into a copy of the default
  configuration. Thus we get an instance.

server instance
  A server instance is a copy of the server definition including the
  modified server configuration. A server gets instantiated by the
  configuration file parser. The concept of server instances has been
  introduced because we wanted Serveez to have the following features.
  A single server can have multiple instances with different behaviour
  due to different server configurations. A server instance can be
  bound to multiple port configurations. Different server instances (of
  the same and/or different server type) can share the same port
  configuration.

port configuration
  A port configuration in Serveez is represented by the `svz_portcfg_t'
  structure. Depending on a shared flag it contains different type of
  information specifying a transport endpoint. *Note Define ports::,
  for more on this topic. It also can be a special configuration item
  within a server configuration. This is necessary if a server needs
  for some reason a remote transport endpoint. A server instance does
  not usually need to know about the port configuration it is bound to.


File: serveez.info,  Node: Writing servers,  Next: Configuring servers,  Prev: Introduction to servers,  Up: Server

Writing servers
===============

   Serveez is meant to be a server framework. That is why it supports
various ways to implement Internet servers. First of all there are some
servers already included in the main serveez package. (*Note Existing
servers::.)  These are called `Builtin servers'. Another possibility to
add a new server are `Embedded servers' which are shared libraries (or
DLL's) containing the server implementation. These can be dynamically
loaded by Serveez at runtime. This kind of server is also called
`Server modules'.  A third possibility are the `Guile servers' which
allow even unexperienced schemers to write an Internet server.

   This section describes each of the above possibilities in detail.

* Menu:

* Embedded servers::    How to write dynamic server modules
* Guile servers::       Servers using Serveez's guile interface
* Builtin servers::     Servers located in the main project


File: serveez.info,  Node: Embedded servers,  Next: Guile servers,  Up: Writing servers

Embedded servers
----------------

   The core library of Serveez can be used to write standalone server
modules.  Serveez defines a certain interface for shared libraries
which contain such server modules. If Serveez detects an unknown server
type (server type which is not builtin) in its configuration file it
tries to load a shared library containing this server type during
startup.

Prerequisites
.............

   In order to implement a server module you need an existing
installation of Serveez. This can be achieved issuing the following
commands:

  $ ./configure --enable-shared --prefix=/usr/local
  $ make
  $ make install

   After successful installation you are able to compile and link
against the Serveez core API. The headers should be available in
`/usr/local/include' and the library itself (`libserveez.so' or
`libserveez.dll') is located in `/usr/local/lib' if you passed the
configure script `--prefix=/usr/local'.

Server definition
.................

   The interface mentioned in the introduction is defined via the extern
declaration of the server type in the shared library of the server
module.  Imagine you want to implement a server type called `foo'. This
requires the external symbol `foo_server_definition' in the shared
library.  You can achieve this inserting the following lines into your
header file:

  /* Either Unices. */
  extern svz_servertype_t foo_server_definition;
  
  /* Or Windows. */
  __declspec (dllexport) extern svz_servertype_t foo_server_definition;

   The data symbol `foo_server_definition' must be statically filled
with the proper content (*Note Builtin servers::.)


File: serveez.info,  Node: Guile servers,  Next: Builtin servers,  Prev: Embedded servers,  Up: Writing servers

Guile servers
-------------

   This section describes the Guile interface to Serveez which provides
the ability to write servers with Guile.  Of course, you could do this
without any help from Serveez, but it makes the task a lot easier.
This interface reduces the Guile implementation of an Internet server
to a simple data processor.

Special Data Types
..................

   Serveez extends Guile by various new data types which represent
internal data structures of Serveez's core API.

* `#<svz-servertype>' represents a server type.

* `#<svz-server>' represents a server (an instance of a server type).

* `#<svz-socket>' represents a socket structure.

Passing Binary Data
...................

   The new binary data type (`#<svz-binary>') provides access to any
kind of unstructured data.  It manages the data exchange between Guile
and Serveez.  There are some conversion functions for strings and lists
which help to process this binary data in a more complex (guile'ish)
way.

 - Function: binary->string binar
  Converts the given binary smob BINARY into a string.  Returns the
  string cell itself.

 - Function: string->binary strin
  Converts the given string cell STRING into a binary smob.  The data
  pointer of the binary smob is marked as garbage which must be free()'d
  in the sweep phase of the garbage collector.

 - Function: binary? binar
  Smob test function: Returns `#t' if the given cell BINARY is an
  instance of the binary smob type.

 - Function: list->binary lis
  Convert the scheme list LIST into a binary smob.  Each of the
  elements of LIST is checked for validity.  The elements can be either
  exact numbers in a byte's range or characters.

 - Function: binary->list binar
  Convert the given binary smob BINARY into a scheme list.  The list is
  empty if the size of BINARY is zero.

 - Function: binary-search binary needl
  This routine searches through the binary smob BINARY for the cell
  NEEDLE.  The latter argument can be either an exact number, character,
  string or another binary smob.  It returns `#f' if the needle could
  not be found and a positive number indicates the position of the first
  occurrence of NEEDLE in the binary smob BINARY.

 - Function: binary-set! binary index valu
  Set the byte at position INDEX of the binary smob BINARY to the value
  given in VALUE which can be either a character or an exact number.

 - Function: binary-ref binary inde
  Obtain the byte at position INDEX of the binary smob BINARY.

 - Function: binary-length binar
  Return the size in bytes of the binary smob BINARY.

 - Function: binary-concat! binary appen
  Append either the binary smob or string APPEND onto the binary smob
  BINARY.  If BINARY has been a simple data pointer reference it is
  then a standalone binary smob as returned by `string->binary'.

 - Function: binary-subset binary start en
  Create a subset binary smob from the given binary smob BINARY.  The
  range of this subset is specified by START and END both inclusive
  (thus the resulting size is = END - START + 1).  With a single
  exception: If END is not given or specified with -1 the routine
  returns all data until the end of BINARY.

 - Function: binary-reverse binar
  Returns a new binary smob with the reverse byte order of the given
  binary smob BINARY.

 - Function: binary-reverse! binar
  Performs an in place reversal of the given binary smob BINARY and
  returns it.

 - Function: binary-long-ref binary index
  Returns the `long' value of the binary smob BINARY at the array index
  INDEX.

 - Function: binary-long-set! binary index value
  Sets the `long' value of the binary smob BINARY at the array index
  INDEX to the given value VALUE.  The procedure returns the previous
  (overridden) value.

 - Function: binary-int-ref binary index
  Returns the `int' value of the binary smob BINARY at the array index
  INDEX.

 - Function: binary-int-set! binary index value
  Sets the `int' value of the binary smob BINARY at the array index
  INDEX to the given value VALUE.  The procedure returns the previous
  (overridden) value.

 - Function: binary-short-ref binary index
  Returns the `short' value of the binary smob BINARY at the array
  index INDEX.

 - Function: binary-short-set! binary index value
  Sets the `short' value of the binary smob BINARY at the array index
  INDEX to the given value VALUE.  The procedure returns the previous
  (overridden) value.

 - Function: binary-char-ref binary index
  Returns the `char' value of the binary smob BINARY at the array index
  INDEX.

 - Function: binary-char-set! binary index value
  Sets the `char' value of the binary smob BINARY at the array index
  INDEX to the given value VALUE.  The procedure returns the previous
  (overridden) value.

Server Definition
.................

   In order to set up a new server type, you use the procedure
`(define-servertype!)'.  This procedure takes one argument which must
be an associative list specifying the server type in detail.  There are
optional and mandatory elements you can set up in this alist.

   The following example shows the overall syntax of this procedure:

  (define-servertype! '(
  
    ;; Mandatory: server type prefix for later use in (define-server!)
    (prefix          . "foo")
  
    ;; Mandatory: server type description
    (description     . "guile foo server")
  
    ;; Mandatory for TCP and PIPE servers: protocol detection
    (detect-proto    . foo-detect-proto)
  
    ;; Optional: global server type initialisation
    (global-init     . foo-global-init)
  
    ;; Optional: server instance initialisation
    (init            . foo-init)
  
    ;; Optional: server instance finalisation
    (finalize        . foo-finalize)
  
    ;; Optional: global server type finalisation
    (global-finalize . foo-global-finalize)
  
    ;; Mandatory for TCP and PIPE servers: socket connection
    (connect-socket  . foo-connect-socket)
  
    ;; Optional: server instance info
    (info-server     . foo-info-server)
  
    ;; Optional: client info
    (info-client     . foo-info-client)
  
    ;; Optional: server instance reset callback
    (reset           . foo-reset)
  
    ;; Optional: server instance notifier
    (notify          . foo-notify)
  
    ;; Mandatory for UDP and ICMP servers: packet handler
    (handle-request  . foo-handle-request)
  
    ;; Mandatory: server type configuration (may be an empty list)
    (configuration   . (
  
      ;; The server configuration is an alist (associative list) again.
      ;; Each item consists of an item name and a list describing the
      ;; item itself.
      ;; Syntax: (key . (type defaultable default))
      (foo-integer       . (integer  #t 0))
      (foo-integer-array . (intarray #t (1 2 3 4 5)))
      (foo-string        . (string   #t "default-foo-string"))
      (foo-string-array  . (strarray #t ("guile" "foo" "server")))
      (foo-hash          . (hash     #t (("foo" . "bar"))))
      (foo-port          . (portcfg  #t foo-port))
      (foo-boolean       . (boolean  #t #t))
    ))))

 - Function: define-servertype! arg
  Guile server definition: This procedure takes one argument containing
  the information about a new server type.  If everything works fine you
  have a freshly registered server type afterwards.  Return `#t' on
  success.

Predefined Procedures
.....................

   The following subset of procedures may be used to implement a Guile
server.  They should be used within the callbacks defined in the
`(define-servertype!)' procedure.  Each of these callbacks gets passed
the appropriate arguments needed to stuff into the following
procedures.  Please have a look at the example Guile servers for the
details.

 - Function: svz:sock? soc
  Returns `#t' if the given cell SOCK is an instance of a valid
  `#<svz-socket>', otherwise `#f'.

 - Function: svz:sock:check-request sock proc
  Set the `check-request' member of the socket structure SOCK to the
  Guile procedure PROC.  Returns the previously handler if there is any.

 - Function: svz:sock:check-oob-request sock proc
  With this procedure you can setup the `check-oob-request' callback of
  the given socket structure SOCK.  The previous callback is replaced
  by the PROC procedure and will be returned if there was set any
  before.  The callback is run whenever urgent data (out-of-band) has
  been detected on the socket.

 - Function: svz:sock:send-oob sock oo
  This procedure expects a TCP `#<svz-socket>' in SOCK and an exact
  number or single character in OOB.  The byte in OOB is sent as urgent
  (out-of-band) data through the underlying TCP stream.  The procedure
  returns `#t' on successful completion and otherwise (either it failed
  to send the byte or the passed socket is not a TCP socket) `#f'.

 - Function: svz:sock:handle-request sock proc
  Set the `handle-request' member of the socket structure SOCK to the
  Guile procedure PROC.  The procedure returns the previously set
  handler if there is any.

 - Function: svz:sock:boundary sock boundar
  Setup the packet boundary of the socket SOCK.  The given string value
  BOUNDARY can contain any kind of data.  If you pass an exact number
  value the socket is setup to parse fixed sized packets.  In fact this
  procedure sets the `check-request' callback of the given socket
  structure SOCK to a predefined routine which runs the
  `handle-request' callback of the same socket when it detected a
  complete packet specified by BOUNDARY.  For instance you can setup
  Serveez to pass your `handle-request' procedure text lines by calling
  `(svz:sock:boundary sock "\n")'.

 - Function: svz:sock:floodprotect sock fla
  Set or unset the flood protection bit of the given socket SOCK.
  Returns the previous value of this bit (#t or #f).  The FLAG argument
  must be either boolean or an exact number and is optional.

 - Function: svz:sock:print sock buffe
  Write the string buffer BUFFER to the socket SOCK.  The procedure
  accepts binary smobs too.  Return `#t' on success and `#f' on failure.

 - Function: svz:sock:final-print soc
  This procedure schedules the socket SOCK for shutdown after all data
  within the send buffer queue has been sent.  The user should issue
  this procedure call right *before* the last call to
  `(svz:sock:print)'.

 - Function: svz:sock:no-delay sock enabl
  Turns the Nagle algorithm for the TCP socket SOCK on or off depending
  on the optional ENABLE argument.  Returns the previous state of this
  flag (`#f' if Nagle is active, `#t' otherwise).  By default this flag
  is switched off.  This socket option is useful when dealing with small
  packet transfer in order to disable unnecessary delays.

 - Function: svz:sock:send-buffer soc
  Return the send buffer of the socket SOCK as a binary smob.

 - Function: svz:sock:send-buffer-size sock siz
  This procedure returns the current send buffer size and fill status in
  bytes of the socket SOCK as a pair of exact numbers.  If the optional
  argument SIZE is given the send buffer will be set to the specified
  size in bytes.

 - Function: svz:sock:receive-buffer soc
  Return the receive buffer of the socket SOCK as a binary smob.

 - Function: svz:sock:receive-buffer-size sock siz
  Returns the current receive buffers size and fill status in bytes of
  the socket SOCK as a pair of exact numbers.  If the optional argument
  SIZE is given the receive buffer will be set to the specified size in
  bytes.

 - Function: svz:sock:receive-buffer-reduce sock lengt
  Dequeue LENGTH bytes from the receive buffer of the socket SOCK which
  must be a valid `#<svz-socket>'.  If the user omits the optional
  LENGTH argument, all of the data in the receive buffer gets dequeued.
  Returns the number of bytes actually shuffled away.

 - Function: svz:sock:connect host proto por
  Establishes a network connection to the given HOST [ :PORT ].  If
  PROTO equals `PROTO_ICMP' the PORT argument is ignored.  Valid
  identifiers for PROTO are `PROTO_TCP', `PROTO_UDP' and `PROTO_ICMP'.
  The HOST argument must be either a string in dotted decimal form, a
  valid hostname or an exact number in host byte order.  When giving a
  hostname this operation might be blocking.  The PORT argument must be
  an exact number in the range from 0 to 65535, also in host byte
  order.  Returns a valid `#<svz-socket>' or `#f' on failure.

 - Function: svz:sock:disconnected sock proc
  Set the `disconnected-socket' member of the socket structure SOCK to
  the Guile procedure PROC.  The given callback runs whenever the
  socket is lost for some external reason.  The procedure returns the
  previously set handler if there is one.

 - Function: svz:sock:kicked sock proc
  Sets the `kicked-socket' callback of the given socket structure SOCK
  to the Guile procedure PROC and returns any previously set procedure.
  This callback gets called whenever the socket gets closed by Serveez
  intentionally.

 - Function: svz:sock:trigger sock proc
  Sets the `trigger' callback of the socket structure SOCK to the Guile
  procedure PROC and returns any previously set procedure.  The
  callback is run when the `trigger-condition' callback returned `#t'.

 - Function: svz:sock:trigger-condition sock proc
  This procedure sets the `trigger-condition' callback for the socket
  structure SOCK to the Guile procedure PROC.  It returns the
  previously set procedure if available.  The callback is run once every
  server loop indicating whether the `trigger' callback should be run
  or not.

 - Function: svz:sock:idle sock proc
  This procedure sets the `idle' callback of the socket structure SOCK
  to the Guile procedure PROC.  It returns any previously set
  procedure.  The callback is run by the periodic task scheduler when
  the `idle-counter' of the socket structure drops to zero.  If this
  counter is not zero it gets decremented once a second.  The `idle'
  callback can reset `idle-counter' to some value and thus can
  re-schedule itself for a later task.

 - Function: svz:sock:idle-counter sock counte
  This functions returns the socket structure SOCK's current
  `idle-counter' value.  If the optional argument COUNTER is given, the
  function sets the `idle-counter'.  Please have a look at the
  `(svz:sock:idle)' procedure for the exact meaning of this value.

 - Function: svz:sock:data sock dat
  Associate any kind of data (any Guile object) given in the argument
  DATA with the socket SOCK.  The DATA argument is optional.  The
  procedure always returns a previously stored value or an empty list.

 - Function: svz:sock:parent sock paren
  Return the given socket's SOCK parent and optionally set it to the
  socket PARENT.  The procedure returns either a valid `#<svz-socket>'
  object or an empty list.

 - Function: svz:sock:referrer sock referre
  Return the given socket's SOCK referrer and optionally set it to the
  socket REFERRER.  The procedure returns either a valid
  `#<svz-socket>' or an empty list.

 - Function: svz:sock:server sock serve
  This procedure returns the `#<svz-server>' object associated with the
  given argument SOCK.  The optional argument SERVER can be used to
  redefine this association and must be a valid `#<svz-server>' object.
  For a usual socket callback like `connect-socket' or
  `handle-request', the association is already in place.  But for
  sockets created by `(svz:sock:connect)', you can use it in order to
  make the returned socket object part of a server.

 - Function: svz:sock:local-address sock addres
  This procedure returns the current local address as a pair like
  `(host . port)' with both entries in network byte order.  If you pass
  the optional argument ADDRESS, you can set the local address of the
  socket SOCK.

 - Function: svz:sock:remote-address sock addres
  This procedure returns the current remote address as a pair like
  `(host . port)' with both entries in network byte order.  If you pass
  the optional argument ADDRESS, you can set the remote address of the
  socket SOCK.

 - Function: svz:sock:find iden
  The given argument IDENT must be a pair of numbers where the car is a
  `#<svz-socket>''s identification number and the cdr the version
  number.  The procedure returns either the identified `#<svz-socket>'
  or `#f' if the given combination is not valid anymore.

 - Function: svz:sock:ident soc
  This procedure returns a pair of numbers identifying the given
  `#<svz-socket>' SOCK which can be passed to `(svz:sock:find)'.  This
  may be necessary when you are passing a `#<svz-socket>' through
  coserver callback arguments in order to verify that the passed
  `#<svz-socket>' is still valid when the coserver callback runs.

 - Function: svz:sock:protocol soc
  Returns one of the `PROTO_TCP', `PROTO_UDP', `PROTO_ICMP',
  `PROTO_RAW' or `PROTO_PIPE' constants indicating the type of the
  socket structure SOCK.  If there is no protocol information available
  the procedure returns `#f'.

 - Function: svz:read-file port siz
  This procedure returns either a binary smob containing a data block
  read from the open input port PORT with a maximum number of SIZE
  bytes or the end-of-file object if the underlying ports end has been
  reached.  The size of the returned binary smob may be less than the
  requested size SIZE if it exceed the current size of the given port
  PORT.  The procedure throws an exception if an error occurred while
  reading from the port.

 - Function: svz:htons hostshor
  The `(svz:htons)' function converts the 16 bit short integer
  HOSTSHORT from host byte order to network byte order.

 - Function: svz:ntohs netshor
  The `(svz:ntohs)' function converts the 16 bit short integer NETSHORT
  from network byte order to host byte order.

 - Function: svz:htonl hostlon
  The `(svz:htonl)' function converts the 32 bit long integer HOSTLONG
  from host byte order to network byte order.

 - Function: svz:ntohl netlon
  The `(svz:ntohl)' function converts the 32 bit long integer NETLONG
  from network byte order to host byte order.

 - Function: svz:inet-aton addres
  Converts the Internet host address ADDRESS from the standard
  numbers-and-dots notation into binary data in network byte order.
  The `(svz:inet-aton)' function returns `#f' if the address is invalid.

 - Function: svz:inet-ntoa addres
  The `(svz:inet-ntoa)' function converts the Internet host address
  ADDRESS given in network byte order to a string in standard
  numbers-and-dots notation.

 - Function: svz:server? serve
  Returns `#t' if the given cell SERVER is an instance of a valid
  `#<svz-server>', otherwise `#f'.

 - Function: svz:server:listeners serve
  Returns a list of listening `#<svz-socket>' smobs to which the given
  server instance SERVER is currently bound, or an empty list if there
  is no such binding yet.

 - Function: svz:server:config-ref server ke
  This procedure returns the configuration item specified by KEY of the
  given server instance SERVER.  You can pass this function a socket
  too.  In this case the procedure will lookup the appropriate server
  instance itself.  If the given string KEY is invalid (not defined in
  the configuration alist in `(define-servertype!)') then it returns an
  empty list.

 - Function: svz:server:state-set! server key valu
  Associates the Guile object VALUE with the string KEY.  The given
  SERVER argument can be both, a `#<svz-server>' or a `#<svz-socket>'.
  Returns the previously associated object or an empty list if there
  was no such association.  This procedure is useful for server
  instance state savings.

 - Function: svz:server:state-ref server ke
  Returns the Guile object associated with the string value KEY which
  needs to be set via `(svz:server:state-set!)' previously.  Otherwise
  the return value is an empty list.  The given SERVER argument must be
  either a valid `#<svz-server>' object or a `#<svz-socket>'.

 - Function: svz:server:state->hash serve
  Converts the SERVER instance's state into a Guile hash.  Returns an
  empty list if there is no such state yet.

 - Function: serveez-port? name
  Returns `#t' if the given string NAME corresponds with a registered
  port configuration, otherwise the procedure returns `#f'.

 - Function: serveez-server? name
  Checks whether the given string NAME corresponds with an instantiated
  server name and returns `#t' if so.

 - Function: serveez-servertype? name
  This procedure checks whether the given string NAME is a valid server
  type prefix known in Serveez and returns `#t' if so.  Otherwise it
  returns `#f'.

 - Function: serveez-exceptions enabl
  Controls the use of exceptions handlers for the Guile procedure calls
  of Guile server callbacks.  If the optional argument ENABLE set to
  `#t' exception handling is enabled and if set to `#f' exception
  handling is disabled.  The procedure always returns the current value
  of this behaviour.

 - Function: serveez-nuke voi
  This procedure can be used to schedule Serveez for shutdown within
  Guile.  Serveez will shutdown all network connections and terminate
  after the next event loop.  You should use this instead of issuing
  `(quit)'.

 - Function: serveez-load fil
  This procedure can be used as a replacement for `(primitive-load)' in
  serveez configuration files.  It tries to locate the given filename
  FILE in the paths returned by `(serveez-loadpath)'.  If FILE cannot
  be loaded the procedure returns `#f'.

 - Function: serveez-loadpath arg
  Make the search path for the Serveez core library accessible for
  Guile.  Returns a list a each path as previously defined.  Can
  override the current definition of this load path.  The load path is
  used to tell Serveez where it can find additional server modules.

 - Function: serveez-interfaces arg
  Make the list of local interfaces accessible for Guile.  Returns the
  local interfaces as a list of ip addresses in dotted decimal form.  If
  another list is given in ARGS it should contain the new list of local
  interfaces.

 - Function: getrpc ar
 - Function: getrpcent
 - Function: getrpcbyname name
 - Function: getrpcbynumber number
  Lookup a network rpc service by name or by service number, and return
  a network rpc service object.  The `(getrpc)' procedure will take
  either a rpc service name or number as its first argument; if given
  no arguments, it behaves like `(getrpcent)'.

 - Function: setrpc stayope
 - Function: setrpcent stayopen
 - Function: endrpcent
  The `(setrpc)' procedure opens and rewinds the file `/etc/rpc'.  If
  the STAYOPEN flag is non-zero, the net data base will not be closed
  after each call to `(getrpc)'.  If STAYOPEN is omitted, this is
  equivalent to `(endrpcent)'.  Otherwise it is equivalent to
  `(setrpcent stayopen)'.

 - Function: portmap prognum versnum protocol por
  A user interface to the portmap service, which establishes a mapping
  between the triple [PROGNUM,VERSNUM,PROTOCOL] and PORT on the
  machine's portmap service.  The value of PROTOCOL is most likely
  `IPPROTO_UDP' or `IPPROTO_TCP'.  If the user omits PROTOCOL and PORT,
  the procedure destroys all mapping between the triple
  [PROGNUM,VERSNUM,*] and ports on the machine's portmap service.

 - Function: portmap-list addres
  This procedure returns a list of the current RPC program-to-port
  mappings on the host located at IP address ADDRESS.  When you leave
  this argument it defaults to the local machine's IP address.  This
  routine can return an empty list indicating either there is no such
  list available or an error occurred while fetching the list.

 - Function: svz:coserver:dns host callback ar
  This procedure enqueues the HOST string argument into the internal
  DNS coserver queue.  When the coserver responds, the Guile procedure
  CALLBACK is run as `(callback addr arg)'.  The ADDR argument passed
  to the callback is a string representing the appropriate IP address
  for the given hostname HOST.  If you omit the optional argument ARG
  it is run as `(callback addr)' only.  The ARG argument may be
  necessary if you need to have the callback procedure in a certain
  context.

 - Function: svz:coserver:reverse-dns addr callback ar
  This Guile procedure enqueues the given ADDR argument which must be
  an IP address in network byte order into the internal reverse DNS
  coserver queue.  When the coserver responds, the Guile procedure
  CALLBACK is run as `(callback host arg)' where HOST is the hostname
  of the requested IP address ADDR.  The last argument ARG is optional.

 - Function: svz:coserver:ident sock callback ar
  This procedure enqueues the given `#<svz-socket>' SOCK into the
  internal ident coserver queue.  When the coserver responds, it runs
  the Guile procedure CALLBACK as `(callback user arg)' where USER is
  the corresponding username for the client connection SOCK.  The ARG
  argument is optional.

Callback Prototypes
...................

   The Guile interface of Serveez is completely callback driven.
Callbacks can be set up in the associative list passed to
`(define-servertype!)', or by using the predefined procedures described
in the previous section.  Each of the callbacks is passed certain
arguments and is meant to return specific values to indicate success or
failure.  This section describes each of these callbacks.

`(global-init #<svz-servertype>)'
  This callback is invoked once for every type of server right after
  the `(define-servertype!)' statement.  Here you can initialise
  resources shared between all instances of your server type.  The
  callback is optional and can be set up in `(define-servertype!)'.  It
  should return zero to indicate success and non-zero to indicate
  failure.  If the global initialiser fails, Serveez will refuse to
  register the server type.

`(global-finalize #<svz-servertype>)'
  If you want to free shared resources, which were possibly allocated
  within the global initialiser, you can do so here.  The callback is
  invoked when Serveez shuts down (issued by `(serveez-nuke)') or the
  server type gets unregistered for some reason.  It should return zero
  to signal success.  The callback can be set up in
  `(define-servertype!)' and is optional.

`(init #<svz-server>)'
  Within this callback you can initialise everything you might need for
  a single instance of your server.  The callback is invoked for each
  server instance which has been created by `(define-server!)' and
  should return zero to indicate success, otherwise Serveez rejects the
  server instance.  The callback can be set up in `(define-servertype!)'
  and is optional.

`(finalize #<svz-server>)'
  The server instance finaliser gets its instance representation passed
  as argument.  You need to free all resources used by this server
  instance which might have been allocated within the server instance
  initialiser or consumed while running.  You can set this callback in
  the `(define-servertype!)' statement.  The callback is optional and
  should return zero to indicate success.

`(detect-proto #<svz-server> #<svz-socket>)'
  Connection oriented protocols like TCP and PIPE allow more than one
  server to be listening on the same network port.  Therefore, it is
  necessary to be able to detect the type of client connecting to a
  port.

  This callback takes two arguments; the first is the server instance
  and the second is the client socket object containing the client
  connection information.  You can set up this callback in the
  `(define-servertype!)' statement.

  Serveez may invoke this callback several times as data becomes
  available from the client until one of the servers recognises it.
  The servers can retrieve the data received so far using the
  `(svz:sock:receive-buffer)' call.

  To indicate successful client detection, you need to return a non-zero
  value.  (Note that for historical reasons, this is inconsistent with
  other functions which return zero on successful completion.)  Once the
  server has indicated success, Serveez invokes any further callbacks
  for the connection only on that server.

  If no server has recognised the client after the first 16 bytes,
  Serveez will close the connection.  The connection will also be
  closed if the client has not sent enough data for a server to
  recognise it within 30 seconds of connecting.

  If multiple servers are listening on the same network port, Serveez
  invokes this callback for each of them in an arbitrary order.  Only
  one server at most should indicate successful detection.

  This callback is mandatory for servers which get bound to connection
  oriented protocol (TCP and PIPE) port configurations by
  `(bind-server!)'.

`(connect-socket #<svz-server> #<svz-socket>)'
  If the client detection signalled success, this callback is invoked to
  assign the client connection to a server instance.  The arguments are
  the same as the detection callback.  In this callback you can assign
  all the connection specific callbacks for your server and perform some
  initial tasks.  Basically you should specify the `handle-request'
  and/or `check-request' callback.  This can be achieved by calling
  `(svz:sock:handle-request)' and `(svz:sock:check-request)'.  The
  `connect-socket' callback is also mandatory for connection oriented
  protocols and must be defined in `(define-servertype!)'.  On success
  you should return zero, otherwise the connection will be shutdown by
  Serveez.

`(info-server #<svz-server>)'
  This callback gets invoked when requested by the builtin *Note
  Control Protocol Server::.  The callback is optional and can be set
  up in `(define-servertype!)'.  The returned character string can be
  multiple lines separated by `\r\n' (but without a trailing
  separator).  Usually you will return information about the server
  instance configuration and/or state.

`(info-client #<svz-server> #<svz-socket>)'
  This callback is optional.  You can set it up in the
  `(define-servertype!)' procedure.  It is meant to provide socket
  structure specific information.  (The socket structure is a
  client/child of the given server instance.)  You need to return a
  single line character string without trailing newlines.  The
  information provided can be requested by the builtin *Note Control
  Protocol Server::.

`(notify #<svz-server>)'
  The server instance notifier callback will be invoked whenever there
  is idle time available.  In practice, it is run approximately once a
  second.  A server instance can use it to perform periodic tasks.  The
  callback is optional and can be set up in `(define-servertype!)'.

`(reset #<svz-server>)'
  This callback is invoked when the Serveez process receives a `SIGHUP'
  signal which can be issued via `killall -HUP serveez' from user land.
  If the underlying operating system does not provide `SIGHUP' there
  is no use for this callback.  It provides the possibility to perform
  asynchronous tasks scheduled from outside Serveez.  You can
  optionally set it up in the `(define-servertype!)' procedure.

`(handle-request #<svz-socket> #<svz-binary> size)'
  This callback is invoked whenever a complete packet has been detected
  in the receive buffer.  The packet data is passed to the callback as a
  `#<svz-binary>'.  The SIZE argument is passed for convenience and
  specifies the length of the packet in bytes.

  The detection, and therefore the invocation, can be made in one of two
  ways.  When Serveez can determine itself when a packet is complete,
  the callback will be invoked directly.  Serveez can make this
  determination for connections with packet oriented protocols such as
  UDP and ICMP, or if you tell Serveez how to parse the packet using
  `(svz:sock:boundary sock delimiter)' or `(svz:sock:boundary sock
  size)' and do not specify a `check-request' callback.

  Whenever you specify a `check-request' callback to determine when a
  packet is complete, it becomes the responsiblity of that callback to
  invoke `handle-request' itself.

  Serveez recognises two different return value meanings.  For
  connection oriented protocols (TCP and PIPE), zero indicates success
  and non-zero failure; on failure, Serveez will shutdown the
  connection.  For packet oriented protocols (UDP and ICMP), a non-zero
  return value indicates that your server was able to process the
  passed packet data, otherwise (zero return value) the packet can be
  passed to other servers listening on the same port configuration.

  This callback must be specified in `(define-servertype!)' for packet
  oriented protocols (UDP and ICMP) but is optional otherwise.  You can
  modify the callback by calling `(svz:sock:handle-request)'.

`(check-request #<svz-socket>)'
  This callback is invoked whenever new data has arrived in the receive
  buffer.  The receive buffer of the given `#<svz-socket>' can be
  obtained using `(svz:sock:receive-buffer)'.  The callback is
  initially not set and can be set up with `(svz:sock:check-request)'.
  Its purpose is to check whether a complete request was received.  If
  so, it should be handled (by running the `handle-request' callback)
  and removed from the receive buffer (using
  `(svz:sock:receive-buffer-reduce)').  The callback is for connection
  oriented protocols (TCP and PIPE) only.  You should return zero to
  indicate success and non-zero to indicate failure.  On failure
  Serveez shuts the connection down.

`(disconnected #<svz-socket>)'
  The `disconnected' callback gets invoked whenever the socket is lost
  for some external reason and is going to be shutdown by Serveez.  It
  can be set up with `(svz:sock:disconnected)'.

`(kicked #<svz-socket> reason)'
  This callback gets invoked whenever the socket gets closed by Serveez
  intentionally.  It can be set up with `(svz:sock:kicked)'.  The
  REASON argument can be either `KICK_FLOOD', indicating the socket is
  a victim of the builtin flood protection, or `KICK_QUEUE' which
  indicates a send buffer overflow.

`(idle #<svz-socket>)'
  The `idle' callback gets invoked from the periodic task scheduler,
  which maintains a `idle-counter' for each socket structure.  This
  counter is decremented whenever Serveez becomes idle and the callback
  is invoked when it drops to zero.  The `idle' callback can set its
  socket's `idle-counter' to some value with the procedure
  `(svz:sock:idle-counter)' and thus re-schedule itself for a later
  task.  You can set up this callback with `(svz:sock:idle)'.

`(trigger-condition #<svz-socket>)'
  This callback is invoked once every server loop for the socket
  structure.  If you return `#f' nothing else is happening.  Otherwise
  the `trigger' callback will be invoked immediately.  You can set up
  the callback using the procedure `(svz:sock:trigger-condition)'.

`(trigger #<svz-socket>)'
  The `trigger' callback is invoked when the `trigger-condition'
  returns `#t'.  The callback can be set up with the procedure
  `(svz:sock:trigger)'.  Returning a non-zero value shuts the
  connection down.  A zero return value indicates success.  This
  callback can be used to perform connection related updates, e.g. you
  can ensure a certain send buffer fill.

`(check-oob-request #<svz-socket> oob-byte)'
  This callback is invoked whenever urgent data (out-of-band) has been
  detected on a socket.  Initially this event is ignored and the
  callback can be set up with the procedure
  `(svz:sock:check-oob-request)'.  The OOB-BYTE argument is a number
  containing the received out-of-band data byte ranging from 0 to 255.
  If the callback returns non-zero the connection will be shutdown.  A
  zero return value indicates success.  You can use
  `(svz:sock:send-oob)' to send a single out-of-band data byte.

  *Please note*: The urgent data is not supported by all operating
  systems.  Also it does not work for all types of network protocols.
  We verified it to be working for TCP streams on GNU/Linux 2.x.x and
  Windows 95;  let us know if/how it works on other platforms.


File: serveez.info,  Node: Builtin servers,  Prev: Guile servers,  Up: Writing servers

Builtin servers
---------------

   All of the servers listed in *Note Existing servers:: are builtin
servers.  The following sections describe in detail how to setup a new
builtin server type. This kind of server will be part of the Serveez
executable. That is why you should make it configurable in the
configure script via a `--enable-xxxserver' argument.

Making and configuring preparations
...................................

   Serveez is configured and built via automake and autoconf. That is
why you are not supposed to write your own Makefiles but simplified
`Makefile.am's. Automake will automatically generate dependencies and
compiler/linker command lines. Here are the steps you basically need to
follow:

* Change to the `src/' directory in the source tree.

* Edit the `Makefile.am'. Add your sub directory name and library name
  which you are going to create.

* Now create the sub directory and change into it.

* You need to create a new `Makefile.am' therein. If you want to have
  this file `configure'd you need to add a further line to the
  `AC_OUTPUT()' statement in `configure.in' which is in the top level
  directory. You have to put at least the following into the newly
  created `Makefile.am':

    noinst_LIBRARIES = libfoo.a
    libfoo_a_SOURCES = foo-proto.h foo-proto.c
    INCLUDES = $(SERVEEZ_CFLAGS) -I$(top_srcdir)/src
    CLEANFILES = *~
    MAINTAINERCLEANFILES = Makefile.in

* Just have a look at all the other server directories. For more
  information about automake read the info pages.


Server header file `foo-proto.h'
................................

   This file contains at least your server's `extern' declaration of
your server definition which must be available from the outside.  The
`foo' server implements all kinds of configuration items which can be
integers, integer arrays, strings, string arrays, port configurations,
booleans and hash maps. Every item of the server configuration can
later be manipulated from the configuration file.

Server implementation file `foo-proto.c'
........................................

   If you want to define default values for your configuration you have
to define them somewhere and put them into the default configuration
structure. This structure will be used to instantiate your server. For
this example we simply called it simply `foo_config'.

   In order to associate the configuration items in a server
configuration to keywords within the configuration file you have to
define an array of key-value-pairs. This is done in the
`foo_config_prototype' field. There are several macros which make
different associations. These are the `SVZ_REGISTER_*' macros which
take three arguments. The first argument is the keyword which will
occur in the configuration file, the second is the associated item in
your default configuration structure and the last argument specifies if
this item is defaultable or not.

Server definition
.................

   The server definition is in a way the `class' of your server.
Together with the default values (`foo_config_prototype') it serves as a
template for newly instantiated servers. The structure contains a long
and a short description of your server. The short name is used as the
prefix for all server instances of this specific type. The long
description is used in the control protocol (*Note Control Protocol
Server::.). The server definition also contains the callbacks your
server (mandatorily) provides.

Server callbacks
................

   There are several callback routines, which get called in order to
instantiate the server and for describing the actual behaviour of your
server.  Here are the description of all of these callbacks.  Some of
them have to be implemented.  Others have reasonable default values.

`global initializer (optional)'
  This callback is executed once for every type of server.  Here you can
  initialize data or whatever is shared between all instances of your
  server.  For instance the HTTP server initializes its file cache here.

`global finalizer (optional)'
  If you want to free shared resources which were possibly allocated
  within the global initializer you can do so here.  The foo server
  frees its default hash previously allocated in the global initializer.

`instance initializer (mandatory)'
  Within this routine you can initialize everything you might need for
  one instance of your server.  The foo server does not do anything in
  this callback.

`instance finalizer (optional)'
  The server instance finalizer gets its instance representation as
  argument.  You have to free all resources used by this server
  instance.

`protocol detection (mandatory)'
  Because it is possible to have more than one server listening on one
  network port we need to detect the type of client which is connecting
  to this port.  The foo server checks if the first five bytes the
  client was sending is identifying it as a foo client.  This routine
  is getting two arguments where the first one is a pointer to this
  servers instance and the second is the client socket object
  containing all information of the client connection.  This structure
  is described a bit later.  Be patient.  For successful client
  detection return non-zero value.

`socket connection (mandatory)'
  If the client detection signaled success this routine is called to
  assign the client connection to the server instance.  The arguments
  are just the same as in the detection routine.  In this callback you
  can assign all the connection specific callbacks for your server and
  do some initial things.  The foo server sets the `check_request'
  callback to the default `svz_sock_check_request' which is using the
  packet delimiter information to find whole packets.  When a client
  sent such a packet the `handle_request' callback is executed.  That
  is why the foo server assigns the `handle_request' method.

`client info (optional)'
  If this callback is given the control protocol (*Note Control
  Protocol Server::.) can give information about a specific client if
  requested with `stat id NUM'.  The first argument given is the server
  instance and the second one the client's socket structure.  You have
  to return a static single line character string.

`server info (optional)'
  This function is called when listing the server instances via `stat
  all' from the control protocol (*Note Control Protocol Server::.).
  The returned character string might be multilined separated by `\r\n'
  (no trailing separator).  Usually you will return all the server
  configuration information.

`notifier (optional)'
  If this callback is not `NULL' it is called whenever there is some
  time left.  It gets the server instance itself as argument.  Actually
  it gets called every second.

`handle request (mandatory for UDP and ICMP servers)'
  The arguments to this callback are the client's socket structure, the
  address of the packet data and its length.  When implementing a UDP or
  ICMP server you need to return non-zero if your server could process
  the packet.  Thus it is possible that there are multiple UDP servers
  on a single port.

Make your server available
..........................

   You distribute your server by editing the `cfgfile.c' file in the
`src/' directory. There you have to include the servers header file and
add the server definition by calling `svz_servertype_add()'

More detailed description of the callback system and structures
...............................................................

   The client connection information is stored within the `svz_socket_t'
object. All of the client connection specific callbacks get this object
as first argument. Following is a description of the most important
elements of this object.

`int id'
  The socket id is a unique id for a client connection.

`int version'
  This item validates this socket structure. If you pass the `id' and
  `version' to a coserver you can check if the delivered socket
  structure is the original or not within the coserver callback.

`int proto'
  The `proto' flag determines a server sockets protocol type which can
  be `PROTO_PIPE', `PROTO_TCP', `PROTO_UDP', `PROTO_ICMP' or
  `PROTO_RAW'.

`int flags'
  The flag field of the client connection contains informations about
  the state of this connection. See `socket.h' in the `src/libserveez/'
  directory for more information. Basically this bitfield specifies how
  this object is handled by the main server loop.

`int userflags'
  This bitfield could be used for protocol specific information. You
  can use it for any information.

`char *boundary, int boundary_size'
  If you are going to write a packet oriented protocol server you can
  use the `svz_sock_check_request' method to parse packets. These two
  properties describe the packet delimiter.

`char *send_buffer, int send_buffer_size, int send_buffer_fill'
  This is the outgoing data for a client connection object.

`char *recv_buffer, int recv_buffer_size, int recv_buffer_fill'
  Within the receive buffer all incoming data for a connection object is
  stored. This buffer is at least used for the client detection
  callback.

`int read_socket (svz_socket_t)'
  This callback gets called whenever data is available on the socket.
  Normally, this is set to a default function which reads all available
  data from the socket and feeds it to `check_request', but specific
  sockets may need other policies.

`int write_socket (svz_socket_t)'
  This routine is called when data is is valid in the output buffer and
  the socket gets available for writing. You normally leave this
  callback untouched. It simply writes as much data as possible to the
  socket and removes the data from the send buffer.

`int disconnected_socket (svz_socket_t)'
  This gets called whenever the socket is lost for some external reason.

`int connected_socket (svz_socket_t)'
  If some piece of code tries to connect to another host via
  `svz_tcp_connect' this connection might be established some time
  later.  This callback gets called when the socket is finally
  connected.

`int kicked_socket (svz_socket_t, int)'
  We call this whenever the socket gets closed by us. The second
  argument specifies a reason.

`int check_request (svz_socket_t)'
  This gets called whenever data was read from the socket.  Its purpose
  is to check whether a complete request was read, and if it was, it
  should be handled and removed from the input buffer.

`int handle_request (svz_socket_t, char *, int)'
  This gets called when the `check_request' got a valid packet. The
  request arguments contains the actual packet and the second argument
  is the length of this packet including the packet delimiter.

`int idle_func (svz_socket_t)'
  This callback gets called from the periodic task scheduler. Whenever
  `idle_counter' (see below) is non-zero, it is decremented and
  `idle_func' gets called when it drops to zero. `idle_func' can reset
  `idle_counter' to some value and thus can re-schedule itself for a
  later task.

`int idle_counter'
  Counter for calls to `idle_func'.

`void *data'
  Miscellaneous field. Listener keeps array of server instances here.
  This array is `NULL' terminated. Some servers store server specific
  information here.

`void *cfg'
  When the final protocol detection in `svz_sock_detect_proto' has been
  done `cfg' should contain a pointer to the actual configuration hash
  map taken from the server instance object.

Using coservers
...............

   Coservers are designed to complete blocking tasks. Each coserver
runs in its own thread/process. There are several coservers
implemented: the dns, reverse dns and ident coserver. You need to
implement the callback which gets called when a coserver completed its
task. This routine must be a `svz_coserver_handle_result_t'. The first
argument is the actual coserver result which might be `NULL' if the
request could not  be fulfilled and the latter two arguments are the
arguments you specified  yourself when issuing the request. To invoke a
coserver you use one of the `svz_coserver_*' macros. The foo server uses
the reverse dns coserver to identify the host name of the remote client.


File: serveez.info,  Node: Configuring servers,  Next: Existing servers,  Prev: Writing servers,  Up: Server

Some words about server configuration
=====================================

   If you define a server you basically pass an instance name and a
list of items to the `(define-server!)' function. Each item has a name
and a value. A value has a type. We provide several types: integers
(numbers), integer arrays, strings, string arrays, booleans
(yes/no-values), hashes (associations) and port configurations.

   The following table shows how each kind of value is set up in the
configuration file. ITEM is the name of the item to be configured.

Integer
  Example: (item . 42)

Integer array
  Example: (item . (0 1 2 3))

String
  Example: (item . "a character string")

String array
  Example: (item . ("abc" "cba" "bca" "acb"))

Boolean
  A normal boolean in guile is represented by #t or #f. But the
  configuration file parser additional understand some bare words and
  numbers.
  Example: (item . #f)

Hash
  Hash maps associate keys with values. Both must be character strings.
  Example: (item . (key1 . "value1") (key2 . "value2"))

Port configuration
  *Note Define ports::, for more information on this. When configuring
  a port configuration you need to define it via `(define-port!)'
  previously and put its symbolic name into the configuration.
  Example: (item . foo-tcp-port)

   The next chapter describes the servers currently implemented using
Serveez. The configuration items used by each of them are described in
the following format:

`NameOfTheItem (Type, default: DefaultValue, Comments)'
  Description of the configuration item named `NameOfTheItem' (case
  sensitive). `Type' can be either `integer', `integer array',
  `string', `string array', `boolean', `hash' or `port configuration'.
  The `Comments' is an optional text.

   The example configuration file `data/serveez.cfg' contains an example
definition of each server already implemented. You can copy and modify
the example for an easy start.


File: serveez.info,  Node: Existing servers,  Prev: Configuring servers,  Up: Server

Existing servers
================

* Menu:

* HTTP Server::                 Integrated Web Server description
* IRC Server::                  EFNet IRC Server
* Control Protocol Server::     Serveez control center
* Foo Server::                  Example server implementation
* SNTP Server::                 Simple network time protocol server
* Gnutella Spider::             Gnutella Client description
* Tunnel Server::               Description of the port forwarder
* Chat Server::                 Chat Server (aWCS, textSure) description
* Fake Ident Server::           Description of a simple ident server
* Passthrough Server::          Description of the program passthrough server
* Mandel Server::               Distributed Mandelbrot server


File: serveez.info,  Node: HTTP Server,  Next: IRC Server,  Up: Existing servers

HTTP Server
-----------

General description
...................

   The integrated HTTP server was originally meant to be a simple but
fast document server. But now it can even execute CGI scripts. The GET,
HEAD and POST methods are fully functional. Additionally Serveez
produces directory listings when no standard document file (e.g.
`index.html') has been found at the requested document node
(directory).  Furthermore it implements a file cache for speeding up
repetitive HTTP request.

   In comparison to other web server projects like Apache and Roxen this
web server is really fast. Comparative benchmarks will follow.  The
benchmark system is a 233 MHz Mobile Pentium MMX. Both the server and
the client (http_load - multiprocessing http test client) ran on the
same computer.

`Small files'
  The small-file test load consists of 1000 files, each 1KB long,
  requested randomly.

    concurrent fetches   1   10   50  100  200  500  1000
    hits/second        501  520  481  475  420  390   295

`CGI'
  The CGI test load consists of a trivial "hello world" C program. I
  noticed GNU/Linux (2.2.17 in this case, probably others too) to throw
  "Resource temporarily unavailable" errors when fork()ing very fast.
  This limits the test to about 200 concurrent fetches on the test
  system.

`Large files'
  The large-file test load consists of 100 files, each 1MB long,
  requested randomly. Also, each connection is throttled to simulate a
  33.6Kbps modem.  Note that 1000 33.6Kbps connections is 3/4 of a T3.
  There was no problem to get 1000+ concurrent fetches.

Configuration
.............

   The following options can be set from the configuration file.

`indexfile (string, default: index.html)'
  The `indexfile' parameter is the default file served by the HTTP
  server when the user does not specify a file but a document node
  (e.g. `http://www.textsure.net/').

`docs (string, default: ../show)'
  The `docs' parameter is the document root where the server finds its
  web documents.

`userdir (string, default: public_html)'
  Each `~user' request gets converted into the given users home
  directory. The string will be appended to this directory. Its default
  value is `public_html'.

`cgi-url (string, default: /cgi-bin)'
  This parameter is the first part of the URL the HTTP server
  identifies a CGI request. For instance if you specify here `/cgi-bin'
  and the user requests `http://www.textsure.net/cgi-bin/test.pl' then
  the HTTP server tries to execute the program `test.pl' within the
  `cgi-dir' (see below) and pipes its output to the user.

`cgi-dir (string, default: ./cgibin)'
  The `cgi-dir' is the CGI document root (on the server).

`cgi-application (hash, default: empty)'
  Within the MinGW32 and native port you can use this hash to associate
  certain file suffices with applications on your computer (e.g. "pl"
  with "perl"). This is necessary because there is no possibility to
  check whether a file is executable on Win32.

`cache-size (integer, default: 200 kb)'
  This specifies the size of the document cache in bytes for each cache
  entry.

`cache-entries (integer, default: 64)'
  This parameter specifies the maximum number of HTTP file cache entries
  (files). When you instantiate more than one HTTP server the biggest
  value wins. The HTTP file cache is shared by all HTTP servers.
  *Please note*: If your harddrive/filesystem combination proves to be
  faster than the HTTP file cache you should disable it by setting both
  `cache-size' and `cache-entries' to zero.

`timeout (integer, default: 15)'
  The `timeout' value is the amount of time in seconds after which a
  keep-alive connection (this is a HTTP/1.1 feature) will be closed when
  it has been idle.

`keepalive (integer, default: 10)'
  On one keep-alive connection can be served the number of `keepalive'
  documents at all. Then the connection will be closed.  Both this and
  the `timeout' value are just to be on the safe side.  They protect
  against idle and high traffic connections.

`default-type (string, default: text/plain)'
  The `default-type' is the default content type the HTTP server
  assumes if it can not identify a served file by the `types' hash and
  the `type-file' (see below).

`type-file (string, default: /etc/mime.types)'
  This should be a file like the `/etc/mime.types' on Unix systems.  It
  associates file suffices with MIME types.

`types (hash, default: empty)'
  If you want to specify special content types do it here. This
  parameter is a hash map associating file suffices with HTTP content
  types (MIME types).

`admin (string, default: root@localhost)'
  Your address, where problems with the server should be e-mailed.
  This address appears on some server-generated pages, such as error
  documents.

`host (string, default: localhost)'
  This is the native host name of your web server. Sometimes the server
  has to send back its own name to the client. It will use this value.
  Be aware that you cannot invent such a name.

`nslookup (boolean, default: false)'
  If this is true the HTTP server invokes a reverse DNS lookup for each
  client connection in order to replace the remote ip address with the
  remote host name in the access logfile.

`ident (boolean, default: false)'
  If this is true the HTTP server processes identd requests for each
  client connection for logging purposes.

`logfile (string, default: http-access.log)'
  The location of the access logfile. For each HTTP request a line gets
  appended to this file.

`logformat (string, default: CLF)'
  The format of the access logfile. There are special placeholders for
  different kinds of logging information. The default log format is the
  Common Log Format (CLF). It contains a separate line for each
  request. A line is composed of several tokens separated by spaces.
    CLF = host ident authuser date request status bytes
  If a token does not have a value then it is represented by a hyphen
  (-).  The meanings and values of these tokens are as follows:

 `%h (host)'
    The fully-qualified domain name of the client, or its IP number if
    the name is not available.

 `%i (ident)'
    This is the identity information reported by the client. Not
    active, so we will see a hyphen (-).

 `%u (authuser)'
    If the request was for an password protected document, then this is
    the userid used in the request.

 `%t (date)'
    The date and time of the request, in the following format:
      date   = [day/month/year:hour:minute:second zone]
      day    = 2*digit
      month  = 3*letter
      year   = 4*digit
      hour   = 2*digit
      minute = 2*digit
      second = 2*digit
      zone   = (`+' | `-') 4*digit

 `%R (request)'
    The request line from the client, enclosed in double quotes (").

 `%r (referrer)'
    Which document referred to this document.

 `%a (agent)'
    What kind of web browser did the remote client use.

 `%c (status)'
    The three digit status code returned to the client.

 `%l (bytes)'
    The number of bytes in the object returned to the client, not
    including any headers.


File: serveez.info,  Node: IRC Server,  Next: Control Protocol Server,  Prev: HTTP Server,  Up: Existing servers

IRC Server
----------

General description
...................

   Internet Relay Chat. The mother of all chat systems.  The integrated
IRC server is intended to be compatible with the EFNet.  There are no
good possibilities to test this in real life, so it is still under
heavy construction. But it can be used as a standalone server anyway.

   IRC itself is a teleconferencing system, which (through the use of
the client-server model) is well-suited for running on many machines in
a distributed fashion. A typical setup involves a single process (the
server) forming a central point for clients (or other servers) to
connect to, performing the required message delivery/multiplexing and
other functions.

   The server forms the backbone of IRC, providing a point for clients
and servers to connect to. Clients connect to talk to each other.
Servers connect to build up a network of servers. IRC server
connections have to build up a spanning tree. Loops are not allowed.
Each server acts as a central node for the rest of the network it sees.

Configuration
.............

   The following table shows the configuration keys provided. Most of
the configuration items are similar to those of an Hybrid IRC server.
They seem archaic at first sight but IRC operators are used to it.
Refer to the Hybrid documentation for further information. It can be
found on the EFNet web page.

`MOTD-file (string, default: ../data/irc-MOTD.txt)'
  When a user initially joins it will get this file's content as the
  message of the day comment. When changing on disk the server will
  notice that and reload the file automatically.

`INFO-file (string, default: no file)'
  The `INFO-file's content gets displayed when the user issues the
  /INFO command.

`tsdelta (integer, default: 0)'
  This value is the timestamp delta value to UTC (Coordinated Universal
  Time) in seconds.

`channels-per-user (integer, default: 10)'
  Configures the maximum number of channels a single local user can
  join.

`admininfo (string, no default)'
  Some administrative information delivered on the /ADMIN command.

`M-line (string, no default, mandatory)'
  The TCP level configuration of this IRC server. The server info field
  is sometimes given to the client for informational use. The server
  will croak about if the settings do not correspond with the actual
  bindings.  The format of this line is:
    ":" virtual hostname
    ":" optional bind address (real hostname)
    ":" server info: "World's best IRC server"
    ":" port

`A-line (string, no default, mandatory)'
  The administrative info, printed by the /ADMIN command.
    ":" administrative info (department, university)
    ":" the server's geographical location
    ":" email address for a person responsible for the IRC server

`Y-lines (string array, no default, suggested)'
  The connection classes. They are used in other parameters (e.g.
  I-lines).  A Y-line describes a group of connections. You usually
  have at least two Y-lines: One for server connections and one for
  client connections.  Format of each line is:
    ":" class number (higher numbers refer to a higher priority)
    ":" ping frequency (in seconds)
    ":" connect frequency in seconds for servers, 0 for
        client classes
    ":" maximum number of links in this class
    ":" send queue size

`I-lines (string array, no default, mandatory)'
  Authorization of clients, wildcards permitted, a valid client is
  matched <user@ip> OR <user@host>.
    ":" user@ip, you can specify `NOMATCH' here to force
        matching user@host
    ":" password (optional)
    ":" user@host
    ":" password (optional)
    ":" connection class number (YLine)

`O-lines (string array, no default, optional)'
  Authorize operator, wildcards allowed.
    ":" user@host, user@ forces checking ident
    ":" password
    ":" nick

`o-lines (string array, no default, optional)'
  Authorize local operator.
    ":" user@host, user@ forces checking ident
    ":" password
    ":" nick

`C-lines (string array, no default, networked)'
  List of servers to connect to.  Note: C and N lines can also use the
  user@ combination in order to check specific users (ident) starting
  servers. C and N lines are usually given in pairs.
    ":" host name
    ":" password
    ":" server name (virtual)
    ":" port (if not given we will not connect)
    ":" connection class number (YLine)

`N-lines (string array, no default, networked)'
  Servers which may connect.
    ":" host name
    ":" password
    ":" server name (virtual host name)
    ":" password
    ":" how many components of your own server's name to strip
        off the front and be replaced with a `*'.
    ":" connection class number (YLine)

`K-lines (string array, no default, optional)'
  Kill user, wildcards allowed.
    ":" host
    ":" time of day
    ":" user


File: serveez.info,  Node: Control Protocol Server,  Next: Foo Server,  Prev: IRC Server,  Up: Existing servers

Control Protocol Server
-----------------------

General description
...................

   Serveez implements something like a telnet protocol for
administrative purposes. You just need to start a telnet session like:
  $ telnet www.textsure.net 42420
   After pressing <RET> you will be asked for a password which you
might setup passing Serveez the -P argument.  *Note Using Serveez::.
The next section describes the interactive commands available.

Using the Control Protocol
..........................

`help'
  This command will give you a very short help screen of all available
  commands.

`quit'
  This command closes the connection to Serveez.

`restart ident'
  Restarts the internal ident coserver. This is useful if you just want
  to start a new one if the old one died or is otherwise unusable.

`restart dns'
  Restarts the internal dns lookup server.

`restart reverse dns'
  Restarts the internal reverse dns lookup server.

`killall'
  This might be useful if Serveez seems to be unstable but you do not
  want to restart it. With `killall' you disconnect all client network
  connections except the control protocol connections.

`kill id NUM'
  Disconnects a specific connection identified by its ID. These IDs will
  be stated when you type `stat con' (see below).

`stat'
  General statistics about Serveez. This will show you some useful
  information about the computer Serveez is running on and about the
  state of Serveez in general.

`stat coserver'
  Statistics about all running coserver instances.

`stat SERVER'
  This command is for selecting certain server instances to be listed.
  SERVER is one of server names you specified in the configuration file.

`stat id NUM'
  Show statistics about a specific connection. This will give you all
  available information about every connection you specified.  *Note
  Writing servers::, for more information about how to provide these
  information.

`stat con'
  Connection statistics. This will give a list of all socket structures
  within Serveez. If you want more detailed information about specific
  connections, coservers or servers you need to request these
  information with `stat id NUM' or `stat all'.

`stat all'
  Server and coserver instance statistics. This command lists all the
  information about instantiated servers and coservers.  *Note Writing
  servers::, for more information about how to provide these
  information.

`stat cache'
  HTTP cache statistics. This command produces an output something like
  the following where `File' is the short name of the cache entry,
  `Size' the cache size, `Usage' the amount of connections currently
  using this entry, `Hits' the amount of cache hits, `Recent' the cache
  strategy flag (newer entries have larger numbers) and `Ready' is the
  current state of the cache entry.

    File                      Size  Usage  Hits Recent Ready
    zlib-1.1.3-20000531.zip  45393      0     0      1 Yes
    texinfo.tex             200531      0     0      2 Yes
    shayne.txt                2534      0     1      1 Yes
    
    Total : 248458 byte in 3 cache entries

`kill cache'
  Reinitialize the HTTP file cache. Flushes all files from the cache.

Configuration
.............

   There is nothing to be configured yet.


File: serveez.info,  Node: Foo Server,  Next: SNTP Server,  Prev: Control Protocol Server,  Up: Existing servers

Foo Server
----------

General description
...................

   The Foo Server is a simple example on how to write Internet protocol
servers with Serveez. *Note Writing servers::.

Configuration
.............

   There are all kinds of configuration items. They are used to explain
the implementation of servers. A complete list will follow.

`port (port configuration, default: tcp, 42421, *)'
  Sets up the TCP port and local address.

`bar (integer, no default)'
  Some integer value. Printed as server information.

`reply (string, default: Default reply)'
  Some string. Printed as server information.

`messages (string array, default: ...)'
  Some string array which is actually a list of strings. Also printed as
  server information.

`ports (integer array, default: 1, 2, 3, 4)'
  Some array of integer numbers. Printed as server information.

`assoc (hash, default, default: ...)'
  An hash map associating keys with values. Printed as server
  information.

`truth (boolean, default: true)'
  Some boolean value. Printed as server information.


File: serveez.info,  Node: SNTP Server,  Next: Gnutella Spider,  Prev: Foo Server,  Up: Existing servers

SNTP Server
-----------

General
.......

   The SNTP server can be queried with the `netdate' command. It is used
to synchronize time and dates between Internet hosts. The protocol is
described in the ARPA Internet RFC 868. Thus it is not really an SNTP
server as described by RFC 2030 (Simple Network Time Protocol (SNTP)
Version 4 for IPv4, IPv6 and OSI). It is rather an excellent example on
how to implement a UDP server in Serveez.

   This protocol provides a site-independent, machine readable date and
time. The Time service sends back time in seconds since midnight on
January first 1900.

   One motivation arises from the fact that not all systems have a
date/time clock, and all are subject to occasional human or machine
error. The use of time-servers makes it possible to quickly confirm or
correct a system's idea of the time, by making a brief poll of several
independent sites on the network.

Configuration
.............

   The configuration of this server does not require any item.


File: serveez.info,  Node: Gnutella Spider,  Next: Tunnel Server,  Prev: SNTP Server,  Up: Existing servers

Gnutella Spider
---------------

What is it ?
............

   The Gnutella net is a peer-to-peer network which is based on client
programs only. There are no servers. The network itself is formed by
client connections only. Generally the Gnutella network is for sharing
files of any kind.

   This Gnutella spider is for seeking the needle in the haystack. Once
connected to the network it regularly tries to find certain files in
there.  It keeps track of all connected clients and tries to reconnect
them if the current connections are lost.

   Gnutella, however has nothing to do with the GNU project. The
original client is just a free (as in free beer) piece of software.
With Serveez you have a free (as in freedom) way to use it. Have a look
at the Gnutella page for further information.

Configuration
.............

   The Gnutella spider knows the following configurations items.

`net-url (string, default: gnutella-net)'
  If you want to see the host catcher list of this Gnutella spider you
  can connect to this port with any WWW browser at
  `http://host:port/net-url'. The `host:port' combinations depend on
  the bindings.

`hosts (string array, no default)'
  This is the start of the haystack, the initial host list of the
  clients the spider tries to connect to.  Each list item should be of
  the format `ip:port' (e.g. `146.145.85.34:6346').  You can also pass
  Internet host names.  If the port information is left blank it
  defaults to 6346.  If you need some entry point for the Gnutella
  network have a look at `http://www.gnutellahosts.com/' or
  `http://www.gnutellanet.com/'.

`search (string array, default: Puppe3000, Meret Becker)'
  This is the needle. Each search line is either a set of space
  delimited tokens where every token must match. Or a kind of wildcard
  expression including `?' and `*'.  Search lines are always matched
  case insensitive.

`search-limit (integer, default: 30)'
  This limits how many results the Gnutella spider returns to other
  people searching your files. This is for protection against "*"
  search requests.

`max-ttl (integer, default: 5)'
  Every Gnutella packet has got a TTL. This is the maximum TTL allowed
  for outgoing packets. When a packet comes in it gets its TTL value
  decremented and is forwarded to it destination. If however an
  incoming packet has a TTL larger than `max-ttl' the ttl value is set
  to `max-ttl'. This is necessary since most people use far too large
  TTL values.

`ttl (integer, default: 5)'
  When creating a new Gnutella packet we use this as TTL. Please use a
  sane value. This ttl needs not to be as large as it is for IP packets.
  A value below 10 is more than enough. Have a look at the Gnutella page
  for a calculation of a 'sane value'.

`download-path (string, default: /tmp)'
  This is where the spider saves needles in.

`share-path (string, default: /tmp)'
  Here are all the files we share with others. The Gnutella spider will
  recurse into directories. So be careful with this option.

`max-downloads (integer, default: 4)'
  Maximum number of concurrent downloads from the network.

`max-uploads (integer, default: 4)'
  Maximum number of concurrent uploads to the network.

`connection-speed (integer, default: 28)'
  This is what we send as our connection speed in KBit/s. We also use
  this value to throttle down the network transfer rate for file
  uploads.

`min-speed (integer, default: 28)'
  Search for needles on hosts with a minimum speed. Set it to 0 if you
  do not care about that. This value is in KBit/s, too.

`file-extensions (string array, default: empty list)'
  If we get replies on search queries we check if the file extension of
  this reply matches one of these extensions. Useful extensions are
  `mp3' and `mpg'.

`connections (integer, default: 4)'
  This is the number of concurrent connections the Gnutella spider tries
  to keep up to the network. The IP addresses and the port information
  is taken from the host catcher hash.

`force-ip (string, default: not set)'
  You can force the Gnutella spider to send outgoing replies with this
  IP as host information. Must be in dotted decimals notation. This is
  useful if you are behind a masquerading gateway. You need to install
  some kind of port forwarder on the gateway so other people can reach
  you from the outside. Serveez is a good port forwarder.

`force-port (integer, default: not set)'
  Force the Gnutella spider to send outgoing replies with the
  `force-port' as port information. See above for more information.

`disable (boolean, default: false)'
  With this configuration option you can disable the bindings for a
  Gnutella server instance.  This means that no remote client can
  connect without being told so (e.g. by push requests).


File: serveez.info,  Node: Tunnel Server,  Next: Chat Server,  Prev: Gnutella Spider,  Up: Existing servers

Tunnel Server
-------------

General description
...................

   The Tunnel server is for mapping one port configuration to another.
So we should rather speak of a port forwarder. Two port forwarders can
form a tunnel. Generally this means that you can setup Serveez to accept
network or pipe connections in order to pass all transfer data on this
line to another port configuration. This can be useful to work around
gateways and firewalls. When instantiating an ICMP source or destination
you must ensure root privileges for the application. On Windows NT and
Windows 2000 you need to be either logged in as Administrator or have
set the registry key
HKLM\System\CurrentControlSet\Services\Afd\Parameters\DisableRawSecurity
to 1 (DWORD). One of the given examples in `serveez.cfg' shows how you
can setup a tunnel server for forwarding a pipe connection. Please keep
in mind when forwarding a TCP or pipe connection over ICMP or UDP you
loose reliability since the latter two are packet oriented rather than
connection oriented. We are not willing to implement our own TCP stack
to work on ICMP/UDP directly.

   Forwarding between the same types of connection is always possible.
When forwarding to an ICMP tunnel we use a special protocol which we
will outline in the following section.

Extended ICMP protocol specification
....................................

   Since ICMP (Internet Control Message Protocol) does have a fixed
packet format we had to extend it in order to use it for our own
purposes. The protocol field of the IP header contains a binary `1'
which is the identifier for ICMP (e.g. `6' identifies TCP). When
creating an ICMP socket the IP header is always generated by the
kernel. This is the main difference to raw sockets where the IP header
must be generated at userspace level.

   When receiving an ICMP packet it also contains the IP header. When
sending an ICMP packet you must not prepend this IP header. The kernel
will do this itself. The IP header always follows the actual ICMP
header followed by the ICMP packet data. Since this section does not
cover raw sockets we leave the IP header structure out here.

   The modified ICMP message format is as:
Offset         Size           Meaning
0              1              Message type.
1              1              Message type sub code.
2              2              Checksum.
4              2              Senders unique identifier.
6              2              Sequence number.
8              2              Port number.
10             0 - 65506      Packet load.

   Each of these fields can be modified and processed by Serveez and do
not get touched by the kernel at all. The ICMP socket implementation of
Serveez differentiates two types of sockets: listening and connected
ICMP sockets.  This is non-standard because it actually makes no sense
since there is no difference for the kernel. The introduction of these
semantics allow Serveez to forward data between connection-oriented
(TCP and named pipes) and packet-oriented (UDP and ICMP) protocols.

Message type
  Valid message types are for instance `8' for an echo message and `0'
  for its echo reply. These two messages are used for the systems
  builtin ping services. Serveez uses its own message type identifier
  which is `42' (`ICMP_SERVEEZ') by default.

Message type sub code
  Serveez also defines its own message type sub codes described in the
  following table.
  Sub code       Constant identifier          Description
  0              `ICMP_SERVEEZ_DATA'          packet contains data
  1              `ICMP_SERVEEZ_REQ'           unused
  2              `ICMP_SERVEEZ_ACK'           unused
  3              `ICMP_SERVEEZ_CLOSE'         disconnection message
  4              `ICMP_SERVEEZ_CONNECT'       connect message

Checksum
  The checksum field of the ICMP header is used to check the ICMP
  headers and the payloads (packet data) validity. We are using the
  standard Internet Checksum algorithm described in RFC 1071. If the
  check failed we drop the packet.

Senders unique identifier
  The senders identifier field is used to determine if a received packet
  has been sent by the sender itself and should therefore be dropped.
  This happens because each ICMP socket setup for receiving gets all
  sent ICMP packets system wide. Thus Serveez will even be notified if
  the kernel creates some echo reply or destination unreachable message
  due to a request completely outside the scope of Serveez.

Sequence number
  Each connected ICMP socket increments its sequence number when sending
  a packet. Thus a connection message type packet of such a socket
  always has a zero sequence number. This field could (but is not yet)
  also be used to reorder ICMP packets or to detect missing packets.

Port number
  The port field of the modified packet format helps Serveez to
  establish connected ICMP sockets. A simple packet filter detects if a
  received packet is kind of reply to a sockets sent packets by
  comparing this port number.  The packet is dropped if the comparison
  fails and it is not a listening socket.

   Except the data message type subcode all ICMP packets created and
sent by Serveez have a zero payload. The connect message subcode
identifies a new connection and the disconnection message subcode its
shutdown without actually transmitting data. These two subcodes emulate
a TCP connections `connect()', `accept()' and `shutdown()' system call.

Configuration
.............

   This might be the most easiest configuration to setup. You
essentially need to define the source port configuration and the target
port configuration. The `serveez.cfg' in the `data/' directory shows
two example configurations how to tunnel TCP connections over UDP and
ICMP. The UDP tunnel accesses the standard HTTP port 80 and the ICMP
tunnel accesses the standard Telnet port 23.

`source (port configuration, no default)'
  The source port configuration. This is usually the same you bind the
  server to.

`target (port configuration, no default)'
  The target port configuration.


File: serveez.info,  Node: Chat Server,  Next: Fake Ident Server,  Prev: Tunnel Server,  Up: Existing servers

Chat Server
-----------

General description
...................

   The whole Serveez package was originally written by Martin
Grabmueller as a fast C backend for a chat system (now called textSure).
This can be found at `http://www.textsure.net/'. The server implements
two kinds of protocols. One is for the master server which does all the
administrative stuff. The second is for the chat clients (applets or
bots). Basically the chat server is a simple multicast unit.

Specification of the Slave/Master server protocol of aWCS
.........................................................

Master server
  The first client that connects and sends an aWCS initialize message
  (see below) becomes the master server.  When the master server
  disconnects, all clients get kicked.

Other clients
  All other clients have to send the aWCS client initialize message,
  which is the string "aWCS\0" (note the final NUL character, which is
  part of the message). Messages received from those clients are simply
  sent to the master server with the client number of the sender
  prefixed (see `Messages from clients').

Message format
  A request consists of a sequence of characters terminated with the
  NUL character '\0'.

Messages from clients
  All messages from clients are routed to the master server, but
  modified in such a way that some digits and one space precede the
  original message. These digits are the (decimal) client's id.

Messages from the master server
  Messages that come from the master server must have the following
  format:

  The first character is one of the following and has a special meaning:

  Character   Meaning
  0           Send message to all clients.
  1           Send message to the clients denoted in the message.
  2           Report status to the master server.
  3           Kick the clients denoted in the message.
  4           Turn off flood protection for the clients in the message.
  5           Turn on flood protection for the clients in the message.
  6           Initialization message.

  Those special characters are followed by a single space.

  Messages which require additional parameters (multicast for example)
  carry these parameters after the space in a comma separated list of
  client ids in the format mentioned above.  The client id list is
  terminated by the \0 character terminating the request (if no
  parameters follow) or by a single space (if parameters follow).  Note
  that no spaces are allowed in comma separated lists.

    Examples:
    
    0 Hallo Welt\0
      - Send "Hallo Welt\0" to all clients except the
        master server.
    
    1 1,4,6 Gruezi!\0
      - Send "Gruezi\0" to the clients 1, 4 and 6.
    
    2 \0
      - Send status data back to the master server.
    
    3 3,4\0
      - Kicks clients 3 and 4.
    
    4 4,16\0
      - Turn off flood protection for clients 4 and 16.
    
    5 1,5\0
      - Turn on flood protection for clients 1 and 5.
    
    6 \0
      - Initialize data structures and accept the
        connection as the master server.

Status messages for the master server
  The low level server posts messages to the master server on several
  occasions, for example when clients connect, disconnect etc.

  Status messages have the same format as other client messages for the
  master server. The client number in the message is the id of the
  master server itself, followed by a space, the status message type and
  additional parameters.

  Type   Description                  Parameter
  0      Client has connected.        Client id, client IP number:port
  1      Client has disconnected.     Client id, error code
  2      Client got kicked.           Client id, kick reason
  3      Low level server is alive.   42
  4      Notify time elapsed.         42

  Error code     Description
  0              Success
  1              Client closed connection

  Kick reason    Description
  0              Flooding
  1              Output buffer overflow

Configuration
.............

   There is nothing to be configured yet. You should notice that it is
possible to bind this server to both named pipes and TCP ports.


File: serveez.info,  Node: Fake Ident Server,  Next: Passthrough Server,  Prev: Chat Server,  Up: Existing servers

Fake Ident Server
-----------------

General description
...................

   Most systems run the 'ident protocol' on port 113. Internet hosts
can connect to that port and find out what user is having a connection
to the host. For example a webserver can query your username when you
fetch a file (e.g.  Serveez' internal ident-coserver can do that).
Most IRC servers protect themselves by allowing only users that have a
valid ident response. Therefore mIRC (for windoze) has a built in ident
server.  This fake ident server can be used to 'fake' a response. This
is useful when you connect through a masquerading gateway and the
gateway cannot handle ident requests correctly. (Or, of course, you are
using windoze, need an ident response and do not have mIRC at hand.)

   This server has two modes of operation. In one mode all requests get
"ERROR : NO-USER" as response. This is a valid but not very helpful
response.  The other mode makes the server send a valid and useful
response. It contains a system type and a username. The system type is
usually 'UNIX'. Others are valid but never used (at least i have never
seen something else).

Configuration
.............

   This server is easy to configure.

`systemtype (string, default: UNIX)'
  The system type to respond. The username field of the response has
  other meanings depending on this field, so do not make things up
  here. Read the RFC to learn more.

`username (string, default: <NULL>)'
  If no username is set (which means this field does not appear in the
  configuration file) the server runs in the flag-all-requests-as-error
  mode.  Use your favourite nickname here.


File: serveez.info,  Node: Passthrough Server,  Next: Mandel Server,  Prev: Fake Ident Server,  Up: Existing servers

Passthrough Server
------------------

General description
...................

   The program passthrough server provides basic inetd functionality.
Basically it can accept connections and pass this connection to the
standard input (stdin) and standard output (stdout) handles of
programs.  Depending on the platform (operating system) the user is
able to configure different methods how this can be achieved.

Configuration
.............

   This server has different types of configuration options specifying
its behaviour.  Some of them are mandatory and some are optional.  The
very least to configure is the program to be started when a new
connection is made.

`binary (string, no default)'
  This parameter specifies the program to execute when a new connection
  has been accepted.  The parameter is mandatory and must be a fully
  qualified file name (including path).

`directory (string, no default)'
  This will be the working directory of the executed program.  If you
  omit this parameter the server uses the current directory (the
  directory is not changed).

`user (string, no default)'
  If you omit this parameter no user or group will be set for the
  started program.  Otherwise you need to specify this information in
  the format `user[.group]'.  If the group is omitted the user's primary
  group will be used.

`argv (string array, no default)'
  This list of character strings is going to be the program's argument
  list (command line).  If the first list item (which is argv[0] and
  the program's name) is left blank it defaults to the name specified
  in the `binary' parameter.

`do-fork (boolean, default: true)'
  This flag specifies the method used to pass the connection to the
  program.  If it is true the server uses the Unix'ish `fork()' and
  `exec()' method.  Otherwise it will pass the data through a unnamed
  pair of sockets [ or two pairs of anonymous pipes ].

`single-threaded (boolean, default: true)'
  This parameter applies to servers bound to UDP and ICMP port
  configurations only.  For programs which process all incoming packets
  and eventually time out, the program is said to be `single-threaded'
  and should use a true value here.  If a program gets a packets and
  can receive further packets, it is said to be a `multi-threaded'
  program, and should use a false value.

`thread-frequency (integer, default: 40)'
  The optional `thread-frequency' parameter specifies the maximum number
  of program instances that may be spawned from the server within an
  interval of 60 seconds.


File: serveez.info,  Node: Mandel Server,  Prev: Passthrough Server,  Up: Existing servers

Mandel Server
-------------

General description
...................

   The distributed Mandelbrot server is an Internet server completely
written in Guile with the help of the API provided by the underlying
Serveez application.  The reader will not see any occurrence of the
networking API of Guile.

   It implements a protocol called `dnc'.  `dnc' - short for
"Distributed Number Cruncher".  The Mandelbrot server manages the
computation of a graphic visualization of the Mandelbrot set fractal.
Each client can connect to the server and ask for something to calculate
and is meant to send its result back to the server.  Finally the server
produces a bitmap in the XPM format and uses a specified viewer
application to bring it onto your screen.

Configuration
.............

   The server can be setup to manage the calculation of the Mandelbrot
set at various locations (rectangular region in the complex plane), in
a specific pixel resolution and colour depth.  Moreover you can define
the name of the final output file and the viewer application the output
file is displayed with.

`start (string, default: -2.0-1.5i)'
  Specifies the upper left corner of the final bitmap in the complex
  plane.

`end (string, default: +1.1+1.5i)'
  Specifies the lower right corner of the final bitmap in the complex
  plane.

`x-res (integer, default: 320)'
  The real part pixel resolution.

`y-res (integer, default: 240)'
  The imaginary part pixel resolution.

`colors (integer, default: 256)'
  Number of maximum colours used in the bitmap.  Also determines the
  maximum iteration depth.

`outfile (string, default: mandel.xpm)'
  When the Mandel server has managed to calculate the whole bitmap it
  produces an output file in the XPM format.  You can specify the name
  and location of this output file.

`viewer (string, default: xv)'
  Here you can setup your favourite bitmap viewer application.  It
  should be able to parse and display the XPM format.


File: serveez.info,  Node: Coserver,  Next: Porting issues,  Prev: Server,  Up: Top

Coserver
********

* Menu:

* What are coservers::         The use of coservers in Serveez
* Writing coservers::          How to write coservers with Serveez
* Existing coservers::         What kind of coservers already exist ?


File: serveez.info,  Node: What are coservers,  Next: Writing coservers,  Prev: Coserver,  Up: Coserver

What are coservers
==================

   If it is necessary to complete blocking tasks in Serveez you have to
use coservers. The actual implementation differs on platforms. On Unices
they are implemented as processes communicating with Serveez over pipes.
On Win32 Serveez uses threads and shared memory.


File: serveez.info,  Node: Writing coservers,  Next: Existing coservers,  Prev: What are coservers,  Up: Coserver

Writing coservers
=================

Making and configuring preparations
-----------------------------------

   First you have to change into the `src/libserveez/coserver/'
directory of the Serveez package. Then edit the `Makefile.am' and add
your header and implementation file to the `libcoserver_la_SOURCES'
variable.

Coserver header file
--------------------

   You have to declare the coserver handle routine here. This callback
gets the input buffer argument and delivers the output buffer result.
Both of these buffers are supposed to be lines separated by a `\n'.

Coserver implementation file
----------------------------

   Here you need to `#include "libserveez/coserver/coserver.h"' and
implement the coserver handle routine declared in the coserver header
file.  This can be any blocking system call. On successful completion
you can return the result or `NULL' on errors. The input and output
buffers are plain strings and can have any format with one exception.
Because the coservers communicate via a line protocol with Serveez
these buffers must not contain `\n' (0x0d).

Make your coserver available in Serveez
---------------------------------------

   For this you have to edit `coserver.h' and `coserver.c' in the
`src/libserveez/coserver/' directory. In the header file you have to
define a further `COSERVER_*' id (macro) and set the
`MAX_COSERVER_TYPES' define to the appropriate value. Then you should
define a further `svz_coserver_*' macro in the same file.

   In `coserver.c' you have to implement the `svz_coserver_*' macro.
This macro takes three arguments. The first is always specific to your
coserver and is used to create the actual request string. Then follows
the result callback routine, and an optional argument for this
callback. The latter two are simply passed to the
`svz_coserver_send_request()' routine. This routine takes four
arguments where the first is the previously defined `COSERVER_*' id and
the second is the input buffer for the coserver handle routine without
the trailing `\n'.

   Then you need to add your coserver to the `svz_coservertypes' array
specifying the `COSERVER_*' id, the coserver description, the coserver
handle routine discussed above, the number of coserver instances to be
created and an optional initialization routine.


File: serveez.info,  Node: Existing coservers,  Prev: Writing coservers,  Up: Coserver

Existing coservers
==================

Identification (Ident) coserver
-------------------------------

   The Identification protocol is briefly documented in RFC1413. It
provides a means to determine the identity of a user of a particular
TCP connection. Given a TCP port number pair, it returns a character
string which identifies the owner of that connection on the server's
(that is the client's) system.

   This is a connection based application on TCP. A server listens for
TCP connections on TCP port 113 (decimal). Once a connection is
established, the server reads a line of data which specifies the
connection of interest. If it exists, the system dependent user
identifier of the connection of interest is sent as the reply. The
server may then either shut down the connection or it may continue to
read/respond to more queries.

   The Ident coserver is a client to this kind of service. For every
established network connection you can use this service by calling the
appropriate macro from `coserver.h'. But you could also use the Ident
coserver as is without this macro.  The messages from Serveez to this
coserver are formatted this way:

  Format:
  RemoteAddressInDottedDecimals ":" RemotePort ":" LocalPort
  
  Macro:
  svz_coserver_ident (sock, MyIdentCallback, sock->id, sock->version);

   In this context `sock' is of type `svz_socket_t' and
`MyIdentCallback' is something like the following example. Both of the
last two (optional) arguments identify a valid socket structure and
`user' can be `NULL' if there is no ident daemon running on the foreign
machine. The last two argument within the above macro will be the last
two arguments in the callback below. Thus you will know what kind of
data the invocation of the callback is related to.

  Callback:
  int
  MyIdentCallback (char *user, int id, int version)
  {
    printf ("Identified user: %s\n", user);
    return 0;
  }

Domain Name Server (DNS) coserver
---------------------------------

   The DNS coserver is using `gethostbyname()' to translate a given
hostname to the associated IP address. The format of the coserver input
line and the macro from `coserver.h' is shown below. The IRC server is
currently using this coserver for resolving its `?-Lines'.  *Note
Existing servers::, for more information. In the example below
`realhost' is something like `www.textsure.net'.

  Format:
  RemoteHostname
  
  Macro:
  svz_coserver_dns (realhost, irc_connect_server, ircserver, NULL);
  
  Callback:
  int
  irc_connect_server (char *ip, irc_server_t *server)
  {
    printf ("The ip address is: %s\n", ip);
    return 0;
  }

Reverse Domain Name Server (reverse DNS) coserver
-------------------------------------------------

   As easily guessed from the name this coserver is just doing the
reverse as the DNS coserver. It translates a given IP address into a
hostname using `gethostbyaddr()'. In the macro the ip address is given
as an `unsigned long' in host byte order. The Reverse DNS coserver
itself takes something like `192.168.2.1'.

  Format:
  RemoteAddressInDottedDecimals
  
  Macro:
  svz_coserver_reverse (addr, MyReverseCallback, sock->id, sock->version);
  
  Callback:
  int
  MyReverseCallback (char *host, int id, int version)
  {
    printf ("Hostname is: %s\n", host);
    return 0;
  }


File: serveez.info,  Node: Porting issues,  Next: Bibliography,  Prev: Coserver,  Up: Top

Porting issues
**************

   Serveez was always designed with an eye on maximum portability.
Autoconf and Automake have done a great job at this.  A lot of
`#define''s help to work around some of the different Unix' oddities.
Have a look at `config.h' for a complete list of all these conditionals.

   Most doubtful might be the Win32 port. There are three different
ways of compiling Serveez on Win32: Using Cygwin, using MinGW (both
gcc) and using the M$ Visual C++ compiler. The Cygwin version of
Serveez depends on the Unix emulation layer DLL `cygwin1.dll'. All
three versions work but it is preferable to use MinGW (or M$ Visual
C++) for performance reasons.  The Cygwin version is slow and limited
to a very low number (some 64) of open files/network connections.

   There are major differences between the Win32 and Unix
implementations due to the completely different API those systems
provide.

Processes and Threads
  Because process communication is usually done by a pair of
  unidirectional pipes we chose that method in order to implement the
  coservers in Unix.  The Win32 implementation are threads which are
  still part of the main process.

Sockets and Handles
  On Win32 systems there is a difference in network sockets and file
  descriptors. Thus we had to implement quite a complex main socket
  loop.

Named Pipes
  Both systems Unix and Win32 do provide this functionality (Windows NT
  4.0 and above). The main differences here are the completely
  different APIs.  On a common Unix you create a named pipe within the
  filesystem via `mkfifo()'. On Win32 you have to `CreateNamedPipe()'
  which will create some special network device. A further difference
  is what you can do with these pipes. On Win32 systems this `network
  device' is valid on remote machines.  Named pipes on Unix are
  unidirectional, on Win32 they are bidirectional and instantiatable.

Winsock Versions
  There are some difference between the original Winsock 1.1 API and
  the new version 2.2.x. In a nutshell, WinSock 2 is WinSock 1.1 on
  steroids, it's a superset of 1.1's APIs and architecture. In addition
  to its new features, it also clarifies existing ambiguities in the
  1.1 WinSock specification and adds new extensions that take advantage
  of operating system features and enhance application performance and
  efficiency. Finally, WinSock 2 includes a number of new
  protocol-specific extensions. These extensions -such as multicast
  socket options- are relegated to a separate annex, since the main
  WinSock 2 protocol specification is protocol-independent.

  The Winsock DLL and import library for version 1.1 are `wsock32.dll'
  and `wsock32.lib' and for version 2.2 it is `ws2_32.dll' and
  `ws2_32.lib'. Serveez is currently using version 2.2.

  The Winsock API is still a bit buggy. Connected datagram behaviors are
  not pertinent to any WinSock 2 features, but to generic WinSock. On
  Win95 it is possible to use `recvfrom()/WSARecvFrom()' on a
  "connected" UDP socket, but on NT4 `recvfrom()/WSARecvFrom()' fail
  with 10056 (`WSAEISCONN'). NOTE: `sendto()/WSASendTo()' fail with
  `WSAEISCONN' on both (which I do not see any reason for, but anyway
  ...).

Raw sockets on Windows systems
  Raw sockets require Winsock 2. To use them under Windows NT/2000, you
  must be logged in as an Administrator. On any other Microsoft's we
  were trying to use the `ICMP.DLL' (an idiotic and almost useless API)
  without success. Microsoft says they will replace it as soon as
  something better comes along. (Microsoft's been saying this since the
  Windows 95 days, however, yet this functionality still exists in
  Windows 2000.)  It seems like you cannot send ICMP or even raw
  packets from the userspace of Windows (except via the `ICMP.DLL'
  which is limited to echo requests). We also noticed that you cannot
  receive any packets previously sent. The only thing which works on
  all Windows systems (9x/ME/NT/2000/XP) is receiving packets the
  "kernel" itself generated (like echo replies).  One good thing we
  noticed about Windows 2000 is that the checksums of fragmented ICMP
  packets get correctly recalculated. That is not the case in the
  current Linux kernels.

Miscellaneous
  To use the Win32 Winsock in the Cygwin port, you just need to
  `#define Win32_Winsock' and `#include "windows.h"' at the top of your
  source file(s). You will also want to add `-lwsock32' to the
  compiler's command line so you link against `libwsock32.a'.

  What preprocessor macros do I need to know about ?  We use `_WIN32'
  to signify access to the Win32 API and `__CYGWIN__' for access to the
  Cygwin environment provided by the dll.  We chose `_WIN32' because
  this is what Microsoft defines in VC++ and we thought it would be a
  good idea for compatibility with VC++ code to follow their example.
  We use `_MFC_VER' to indicate code that should be compiled with VC++.

  Why we do not use pipes for coservers ?  Windows differentiates
  between sockets and file descriptors, that is why you can not
  `select()' file descriptors. Please `close()' the pipe's descriptors
  via `CloseHandle()' and not `closesocket()', because this will fail.

  The C run-time libraries have a preset limit for the number of files
  that can be open at any one time. The limit for applications that
  link with the single-thread static library (`LIBC.LIB') is 64 file
  handles or 20 file streams. Applications that link with either the
  static or dynamic multithread library (`LIBCMT.LIB' or `MSVCRT.LIB'
  and `MSVCRT.DLL'), have a limit of 256 file handles or 40 file
  streams.  Attempting to open more than the maximum number of file
  handles or file streams causes program failure.

  As far as I know, one of the big limitations of Winsock is that the
  SOCKET type is *not* equivalent to file descriptor. It is however
  with BSD and POSIX sockets. That is one of the major reasons for
  using a separate data type, SOCKET, not an int, a typical type for a
  file descriptor. This implies that you cannot mix SOCKETs and stdio,
  sorry. This is the case when you use `-mno-cygwin'.

  Actually they are regular file handles, just like any other. There is
  a bug in all 9x/kernel32 libc/msv/crtdll interface implementations
  `GetFileType()' returns `TYPE_UNKNOWN' for socket handles. Since this
  is AFAIK the only unknown type there is, you know you have a socket
  handle. There is a fix in the more recent perl distributions that you
  can use as a general solution. `-loldnames -lperlcrt -lmsvcrt' will
  get you `TYPE_CHAR' for socket handles.

   If you want to compile Serveez with the native M$ Visual C++
compiler you have to go quite a long way. But it is possible anyway. We
assume you got a Cygwin development environment somewhere, the
Developer Studio installation and `serveez' and `guile' in separate
directories.  Please have a look at the `README-Win32' file for more
information.

   Now follows the list on which operating systems and architectures
Serveez has been build and tested successfully.

* FreeBSD 3.3, 4.0, 4.3, 4.4, 4.5, 4.6 on Intel

* FreeBSD 4.0, 4.6 on Alpha

* NetBSD 1.5 on Alpha

* OpenBSD 3.0, 3.1 on Alpha

* OpenBSD 3.1 on Intel

* GNU/Linux 2.x.x on Intel

* GNU/Linux 2.x.x on Alpha

* GNU/Linux 2.2.x on Sparc64 (UltraSparcII + MachV)

* GNU/Linux 2.x.x on PowerPC (RS/6000)

* GNU/Linux 2.4.x on ia64 (Itanium)

* GNU/Linux 2.4.x on StrongARM (iPAQ)

* Solaris 2.6, 2.7 on Sparc32, Sparc64

* SunOS 5.8 on Sparc32

* SunOS 5.6 on Intel

* AIX 4.3 on RS/6000

* MacOS X10.1/Darwin 1.4, 5.4, 5.5 on PowerPC (Macintosh)

* Windows 95 on Intel

* Windows 98 on Intel

* Windows Millennium Edition on Intel

* Windows NT 4.0 on Intel

* Windows 2000 on Intel

* Windows XP on Intel

* IRIX 6.x on MIPS

* Tru64/OSF1 UNIX V4.0 (former Digital UNIX) on Alpha

* Tru64/OSF1 UNIX V5.x (former Digital UNIX) on Alpha

* HP-UX B.11.11 on HP PA-RISC (PA-8700/PA-8600)



File: serveez.info,  Node: Bibliography,  Next: License,  Prev: Porting issues,  Up: Top

Bibliography
************

   This section contain some of the documents and resources we read and
used to implement various parts of this package. They appear in no
specific order.

1. RFC 760
  The Internet Protocol

2. RFC 1071
  Computing the Internet Checksum

3. RFC 1413
  Identification Protocol

4. RFC 1459
  Internet Relay Chat Protocol

5. RFC 1945
  Hypertext Transfer Protocol - HTTP/1.0

6. RFC 2068
  Hypertext Transfer Protocol - HTTP/1.1

7. RFC 2616
  Hypertext Transfer Protocol - HTTP/1.1

8. RFC 768
  User Datagram Protocol

9. RFC 791
  Internet Protocol

10. RFC 777
  Internet Control Message Protocol

11. `http://www.mingw.org/'
  Home of the MinGW (Minimal GNU for Windows) project

12. `http://gnutelladev.wego.com/'
  The Gnutella Protocol

13. `http://www.efnet.org/'
  The official EFNet site (includes Hybrid IRC server)

14. `http://www.sockets.com/'
  Winsock Development Information

15. `http://tangentsoft.net/wskfaq/'
  Winsock Programmer's FAQ


File: serveez.info,  Node: License,  Prev: Bibliography,  Up: Top

License
*******

   GNU General Public License Version 2, June 1991
Serveez is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2, or any later version.

   This software is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
General Public License for more details.

   You should have received a copy of the GNU General Public License
along with this package; see the file COPYING.  If not, write to the
Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
02111-1307, USA.

Copyright (C) 1999, 2000, 2001, 2002 Martin Grabmueller
<mgrabmue@cs.tu-berlin.de>
Copyright (C) 2000, 2001, 2002 Raimund Jacob <raimi@lkcc.org>
Copyright (C) 2000, 2001, 2002 Stefan Jahn <stefan@lkcc.org>
Verbatim copying and distribution of this entire document is permitted
in any medium, provided this notice is preserved.



Tag Table:
Node: Top220
Node: Introduction805
Node: Using Serveez2055
Node: Define ports13024
Node: Define servers24066
Node: Bind servers to ports26549
Node: Concept30092
Node: Server38370
Node: Introduction to servers38753
Node: Writing servers41651
Node: Embedded servers42690
Node: Guile servers44412
Node: Builtin servers80477
Node: Configuring servers92768
Node: Existing servers94813
Node: HTTP Server95654
Node: IRC Server102837
Node: Control Protocol Server107795
Node: Foo Server111178
Node: SNTP Server112354
Node: Gnutella Spider113467
Node: Tunnel Server118355
Node: Chat Server124543
Node: Fake Ident Server128810
Node: Passthrough Server130578
Node: Mandel Server133245
Node: Coserver135301
Node: What are coservers135617
Node: Writing coservers136031
Node: Existing coservers138451
Node: Porting issues141843
Node: Bibliography149883
Node: License150961

End Tag Table
