Originally written by Trevor Talbot (Quension) in October 2004.


Clone Limiting
==============
Bahamut supports limiting the number of connections from a single place,
and this file describes the configuration for that feature.  There are two
kinds of places: a "host" is a single IP (10.0.0.1); a "site" is a single
/24 block of IPs (10.0.0.*).  Clones are the number of connections from a
given place.

Two types of clone limits are supported: local clones are the number of
connections from a place on this server only; global clones refer to
connections on the entire network.  When a clone limit is reached, the
server denies further connections from that place.


Local clone limiting
--------------------
The default local clone limits are set using the local_clones token in the
Options block in ircd.conf; see doc/reference.conf for details.  In the
absence of more specific limits, the defaults will regulate all connections
to the server.

Local limits set using the maxclones token in a Class block override the
defaults; this is typically used with Allow blocks to provide exemptions
for specific hosts.  When a Class block defines a host limit, clients in
that class are implicitly exempt from the default site limit.

Example:

        options { local_clones 1:10; };
        class { name special; maxclones 5; };
        allow { host *@10.0.0.1; class special; };

    Suppose there is one client each connected from 10.0.0.2 - 9 (8 clients
    from 10.0.0.*).  If another client from 10.0.0.2 tries to connect, it
    will be rejected because the default limit of 1 connection per host was
    reached.  Five more clients from 10.0.0.1 will be allowed to connect,
    because the "special" class allows up to 5 connections from a single
    host.

    Note that because the class did not provide a site limit, five clients
    from 10.0.0.1 will always be allowed to connect, despite the default
    limit of 10 per site.  To maintain a site limit for these clients,
    specify one in the class maxclones statement:

        class { name special; maxclones 5:10; };

The default limits can be changed online using the SET DEFLCLONES command.
Note that this setting is not saved and will be lost when the server is
restarted; it is useful for testing or setting temporary limits.

    SET DEFLCLONES                            - to display both limits
    SET DEFLCLONES <host limit>               - to set the host limit
    SET DEFLCLONES <host limit>:<site limit>  - to set both limits

    Supplying a limit of 0 will revert to the internal default.

Specific local limits can be set online using the SET LCLONES command;
these are called "soft" limits and override all other local limits.
A soft host limit also provides an implicit exemption from class and
default site limits.  Like DEFLCLONES, these are temporary.

    SET LCLONES <host/site>                   - to display the limit
    SET LCLONES <host/site> <limit>           - to set the limit

    Use a specific host or site mask, e.g. "10.0.0.1".  Supplying a limit
    of 0 will remove the soft limit; class and default limits will be used
    instead.

Note that it is possible to create some interesting configurations using
the class setting.  For example, this would effectively allow 5 clones from
a specific ident@host, since only clients matching the allow block would get
the increased per-host limit:

    options { local_clones 1; };
    class { name special; maxclones 5; };
    allow { host ident@host; class special; };


Global clone limiting
---------------------
This works in basically the same way as local clone limiting, except that
it considers connections on the entire network, and is intended to be
managed by network services.

The default global clone limits are set using the global_clones token in
the Options block in ircd.conf; see doc/reference.conf for details.  In the
absence of more specific limits, the defaults will regulate all connections
to the server.  Note that to be effective, all servers must share the same
global limits.  A server can only reject new connections to itself; it
cannot tell other servers to do so.

Example:

        options { global_clones 2:6; };

    If there are six clients on other servers on the network, from various
    addresses in the 10.0.0.* block, this server will not allow another
    connection from 10.0.0.1, because the global site limit has already
    been reached.  However, if the remote servers have a higher default,
    they will still allow more clients to connect.

Network services can set specific limits using the SVSCLONE command; these
are referred to as "hard" global clone limits.  A hard host limit provides
an implicit exemption from the default site limit.  The command syntax is
provided here for services authors to reference; it is not accessible to
clients.

    SVSCLONE <host/site> <limit>              - to set the limit

    Use a specific host or site mask, e.g. "10.0.0.*".  Supplying a limit
    of 0 will remove the hard limit.  This setting is stored by all servers
    and propagated on netburst, in a manner similar to SQLINES.

The default limits can be changed online using the SET DEFGCLONES command.
Note that this setting is not saved and will be lost when the server is
restarted; it is useful for testing or setting temporary limits.

    SET DEFGCLONES                            - to display both limits
    SET DEFGCLONES <host limit>               - to set the host limit
    SET DEFGCLONES <host limit>:<site limit>  - to set both limits

    Supplying a limit of 0 will revert to the internal default.

Specific global limits can be set online using the SET GCLONES command;
these are called "soft" global clone limits and override the defaults.
A lower soft limit will also override a service-set hard limit, but it is
not possible to set a soft limit higher than a hard one.  Like DEFGCLONES,
these are temporary.

    SET GCLONES <host/site>                   - to display the limits
    SET GCLONES <host/site> <limit>           - to set the soft limit

    Use a specific host or site mask, e.g. "10.0.0.1".  Supplying a limit
    of 0 will remove the soft limit; hard and default limits will be used
    instead.


Monitoring
----------
Rejection notices for clone connections are sent to usermode +j, in the
following format:

    clone <nick!user@host> (<place> <online>/<limit> <type> <from>)

    <nick!user@host> is the rejected client
    <place> is the host or site mask, e.g. "10.0.0.*"
    <online> is the number of clients currently online from that place
    <limit> is the limit for that place
    <type> is "local" or "global"
    <from> is where the limit was set:
           "default", "soft", "hard", "class <name>"

General statistics about the clones system are available on STATS d.

A list of specific limits is available on STATS D, returned on numeric 225:

    D <host/site> <soft local limit> <soft global> <hard global>


Notes
-----
When local and global limits differ, the lowest limit applies.  This means
you should carefully choose the defaults and how you want to manage the
specific limits, as working with both types of limits at once can be
difficult.

When a client is rejected, its exit reason is one of:

    Too many connections from your host
    Too many connections from your site

It is not told which specific limit was reached.

Very little host/site mask validation is done for the online commands; it
is possible to query and set limits for completely bogus masks.  Such
limits will be retained but never used.
