RFC 1459, IRC : Current implementations


8. Current implementations

   The only current implementation of this protocol is the IRC server,
   version 2.8. Earlier versions may implement some or all of the
   commands described by this document with NOTICE messages replacing

   many of the numeric replies.  Unfortunately, due to backward
   compatibility requirements, the implementation of some parts of this
   document varies with what is laid out.  On notable difference is:

        * recognition that any LF or CR anywhere in a message marks the
          end of that message (instead of requiring CR-LF);

   The rest of this section deals with issues that are mostly of
   importance to those who wish to implement a server but some parts
   also apply directly to clients as well.

8.1. Network protocol: TCP - why it is best used here.

   IRC has been implemented on top of TCP since TCP supplies a reliable
   network protocol which is well suited to this scale of conferencing.
   The use of multicast IP is an alternative, but it is not widely
   available or supported at the present time.

8.1.1. Support of Unix sockets

   Given that Unix domain sockets allow listen/connect operations, the
   current implementation can be configured to listen and accept both
   client and server connections on a Unix domain socket.  These are
   recognized as sockets where the hostname starts with a '/'.

   When providing any information about the connections on a Unix domain
   socket, the server is required to supplant the actual hostname in
   place of the pathname unless the actual socket name is being asked
   for.

8.2. Command Parsing

   To provide useful 'non-buffered' network IO for clients and servers,
   each connection is given its own private 'input buffer' in which the
   results of the most recent read and parsing are kept.  A buffer size
   of 512 bytes is used so as to hold 1 full message, although, this
   will usually hold several commands.  The private buffer is parsed
   after every read operation for valid messages.  When dealing with
   multiple messages from one client in the buffer, care should be taken
   in case one happens to cause the client to be 'removed'.

8.3. Message delivery

   It is common to find network links saturated or hosts to which you
   are sending data unable to send data.  Although Unix typically
   handles this through the TCP window and internal buffers, the server
   often has large amounts of data to send (especially when a new
   server-server link forms) and the small buffers provided in the

   kernel are not enough for the outgoing queue.  To alleviate this
   problem, a "send queue" is used as a FIFO queue for data to be sent.
   A typical "send queue" may grow to 200 Kbytes on a large IRC network
   with a slow network connection when a new server connects.

   When polling its connections, a server will first read and parse all
   incoming data, queuing any data to be sent out. When all available
   input is processed, the queued data is sent. This reduces the number
   of write() system calls and helps TCP make bigger packets.

8.4. Connection 'Liveness'

   To detect when a connection has died or become unresponsive, the
   server must ping each of its connections that it doesn't get a
   response from in a given amount of time.

   If a connection doesn't respond in time, its connection is closed
   using the appropriate procedures.  A connection is also dropped if
   its sendq grows beyond the maximum allowed, because it is better to
   close a slow connection than have a server process block.

8.5. Establishing a server to client connection

   Upon connecting to an IRC server, a client is sent the MOTD (if
   present) as well as the current user/server count (as per the LUSER
   command).  The server is also required to give an unambiguous message
   to the client which states its name and version as well as any other
   introductory messages which may be deemed appropriate.

   After dealing with this, the server must then send out the new user's
   nickname and other information as supplied by itself (USER command)
   and as the server could discover (from DNS/authentication servers).
   The server must send this information out with NICK first followed by
   USER.

8.6. Establishing a server-server connection.

   The process of establishing of a server-to-server connection is
   fraught with danger since there are many possible areas where
   problems can occur - the least of which are race conditions.

   After a server has received a connection following by a PASS/SERVER
   pair which were recognised as being valid, the server should then
   reply with its own PASS/SERVER information for that connection as
   well as all of the other state information it knows about as
   described below.

   When the initiating server receives a PASS/SERVER pair, it too then

   checks that the server responding is authenticated properly before
   accepting the connection to be that server.

8.6.1. Server exchange of state information when connecting

   The order of state information being exchanged between servers is
   essential.  The required order is as follows:

        * all known other servers;

        * all known user information;

        * all known channel information.

   Information regarding servers is sent via extra SERVER messages, user
   information with NICK/USER/MODE/JOIN messages and channels with MODE
   messages.

   NOTE: channel topics are *NOT* exchanged here because the TOPIC
   command overwrites any old topic information, so at best, the two
   sides of the connection would exchange topics.

   By passing the state information about servers first, any collisions
   with servers that already exist occur before nickname collisions due
   to a second server introducing a particular nickname.  Due to the IRC
   network only being able to exist as an acyclic graph, it may be
   possible that the network has already reconnected in another
   location, the place where the collision occurs indicating where the
   net needs to split.

8.7. Terminating server-client connections

   When a client connection closes, a QUIT message is generated on
   behalf of the client by the server to which the client connected.  No
   other message is to be generated or used.

8.8. Terminating server-server connections

   If a server-server connection is closed, either via a remotely
   generated SQUIT or 'natural' causes, the rest of the connected IRC
   network must have its information updated with by the server which
   detected the closure.  The server then sends a list of SQUITs (one
   for each server behind that connection) and a list of QUITs (again,
   one for each client behind that connection).

8.9. Tracking nickname changes

   All IRC servers are required to keep a history of recent nickname
   changes.  This is required to allow the server to have a chance of
   keeping in touch of things when nick-change race conditions occur
   with commands which manipulate them.  Commands which must trace nick
   changes are:

        * KILL (the nick being killed)

        * MODE (+/- o,v)

        * KICK (the nick being kicked)

   No other commands are to have nick changes checked for.

   In the above cases, the server is required to first check for the
   existence of the nickname, then check its history to see who that
   nick currently belongs to (if anyone!).  This reduces the chances of
   race conditions but they can still occur with the server ending up
   affecting the wrong client.  When performing a change trace for an
   above command it is recommended that a time range be given and
   entries which are too old ignored.

   For a reasonable history, a server should be able to keep previous
   nickname for every client it knows about if they all decided to
   change.  This size is limited by other factors (such as memory, etc).

8.10. Flood control of clients

   With a large network of interconnected IRC servers, it is quite easy
   for any single client attached to the network to supply a continuous
   stream of messages that result in not only flooding the network, but
   also degrading the level of service provided to others.  Rather than
   require every 'victim' to be provide their own protection, flood
   protection was written into the server and is applied to all clients
   except services.  The current algorithm is as follows:

        * check to see if client's `message timer' is less than
          current time (set to be equal if it is);

        * read any data present from the client;

        * while the timer is less than ten seconds ahead of the current
          time, parse any present messages and penalize the client by
          2 seconds for each message;

   which in essence means that the client may send 1 message every 2

   seconds without being adversely affected.

8.11. Non-blocking lookups

   In a real-time environment, it is essential that a server process do
   as little waiting as possible so that all the clients are serviced
   fairly.  Obviously this requires non-blocking IO on all network
   read/write operations.  For normal server connections, this was not
   difficult, but there are other support operations that may cause the
   server to block (such as disk reads).  Where possible, such activity
   should be performed with a short timeout.

8.11.1. Hostname (DNS) lookups

   Using the standard resolver libraries from Berkeley and others has
   meant large delays in some cases where replies have timed out.  To
   avoid this, a separate set of DNS routines were written which were
   setup for non-blocking IO operations and then polled from within the
   main server IO loop.

8.11.2. Username (Ident) lookups

   Although there are numerous ident libraries for use and inclusion
   into other programs, these caused problems since they operated in a
   synchronous manner and resulted in frequent delays.  Again the
   solution was to write a set of routines which would cooperate with
   the rest of the server and work using non-blocking IO.

8.12. Configuration File

   To provide a flexible way of setting up and running the server, it is
   recommended that a configuration file be used which contains
   instructions to the server on the following:

        * which hosts to accept client connections from;

        * which hosts to allow to connect as servers;

        * which hosts to connect to (both actively and
          passively);

        * information about where the server is (university,
          city/state, company are examples of this);

        * who is responsible for the server and an email address
          at which they can be contacted;

        * hostnames and passwords for clients which wish to be given

          access to restricted operator commands.

   In specifying hostnames, both domain names and use of the 'dot'
   notation (127.0.0.1) should both be accepted.  It must be possible to
   specify the password to be used/accepted for all outgoing and
   incoming connections (although the only outgoing connections are
   those to other servers).

   The above list is the minimum requirement for any server which wishes
   to make a connection with another server.  Other items which may be
   of use are:

        * specifying which servers other server may introduce;

        * how deep a server branch is allowed to become;

        * hours during which clients may connect.

8.12.1. Allowing clients to connect

   A server should use some sort of 'access control list' (either in the
   configuration file or elsewhere) that is read at startup and used to
   decide what hosts clients may use to connect to it.

   Both 'deny' and 'allow' should be implemented to provide the required
   flexibility for host access control.

8.12.2. Operators

   The granting of operator privileges to a disruptive person can have
   dire consequences for the well-being of the IRC net in general due to
   the powers given to them.  Thus, the acquisition of such powers
   should not be very easy.  The current setup requires two 'passwords'
   to be used although one of them is usually easy guessed.  Storage of
   oper passwords in configuration files is preferable to hard coding
   them in and should be stored in a crypted format (ie using crypt(3)
   from Unix) to prevent easy theft.

8.12.3. Allowing servers to connect

   The interconnection of server is not a trivial matter: a bad
   connection can have a large impact on the usefulness of IRC.  Thus,
   each server should have a list of servers to which it may connect and
   which servers may connect to it.  Under no circumstances should a
   server allow an arbitrary host to connect as a server.  In addition
   to which servers may and may not connect, the configuration file
   should also store the password and other characteristics of that
   link.

8.12.4. Administrivia

   To provide accurate and valid replies to the ADMIN command (see
   section 4.3.7), the server should find the relevant details in the
   configuration.

8.13. Channel membership

   The current server allows any registered local user to join upto 10
   different channels.  There is no limit imposed on non-local users so
   that the server remains (reasonably) consistant with all others on a
   channel membership basis