Skip to main content
Version: 1.0

Server protocol

This is a work-in-progress, as such it is largely incomplete.

Introduction#

This specification describes the P10 protocol as implemented by ircd-yeti, which includes various extentions.

It is based on:

  • "Undernet P10 Protocol and Interface Specification"
  • Raw data sent by ircd-yeti, and
  • The ircd-yeti source code

Concepts#

This specification assumes that you are already familiar with concepts inherent in IRC.

P10 Base64#

The P10 protocol uses a Base64 encoding for "numerics" (discussed below), and for the IP parameter used in the NICK message to maintain human readable data flow while also reducing the size of messages. The Base64 character set used in ircd-yeti is included below, which defines all valid characters allowed in a P10 Base64 string with "A" representing 0 and "]" representing 63.

ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789[]

Whenever this specification refers to "Base64" it is referring to "P10 Base64" as defined here, unless otherwise specified.

Numerics#

The P10 protocol uses a scheme of "numerics" to uniquely identify a client or server within the network. Each server has its own unique numeric (0 -> 4095) and each client has its own numeric within that server (0 -> 262,143). These numerics, as mentioned above, are encoded into a Base64 string.

Server numerics consist of two characters, with the minimum 0 being represented as "AA", and the maximum 4095 being represented as "]]". Client numerics are three characters long, with the minimum 0 being represented by "AAA", and the maximum 262,143 being represented by "]]]" The unique identifier of a client on the network consists of a combination of both the server and client numeric in the format SSCCC.

As an example, consider a server "irc.example.org" configured with the numeric 10, translating to "AK" in Base64. On this server exists the client "UserA" which has been allocated the numeric 63, translating to "AA]" in Base64. Therefore, the unique identifier of this client on the network is "AKAA]". From this we can determine which server the message came from, as well as the client who sent it.

These numerics are used to prefix every message issued on the stream, except for the initial PASS and SERVER messages, which are not prefixed. This discussed more in depth later in this specification.

Note: Some P10 implementation support what are known as "short numerics", which are 1-3 characters in length. These are not discussed in this document since ircd-yeti does not support them.

Tokens#

Message identifiers, also commonly referred to as commands, have both a long form name, and a short for name referred to as a "token". The original aim of tokenisation was to reduce the bandwidth used during network communication by reducing the length of common message identifiers. Today, this isn't nearly as important, although use of an identifier's token form has stuck.

Below is a list of acceptable message identifiers, along with their relevant token, which is used in the server<>server protocol.

Message (command)Token
ACCEPTAP
ACCOUNTAC
ADMINAD
ASLLLL
AWAYA
BURSTB
CERTFPCF
CFEATCT
CHECKCC
CLEARMODECM
CLOAKCK
CONNECTCO
GLINEGL
JUPEJU
NICKN
SERVERS
SHUNSU

Message format#

The general message format for the server<>protocol is much like that defined in RFC 1459, section 2.3.1:

<source> <token> [<parameters>]

The source, token and parameters are separated by spaces (0x20).

The maximum number of parameters is 15, which does not include the source and token.

Implementations MUST only send the token form of a message identifier, except for the initial PASS and SERVER messages; however, an implementation MAY choose to parse both the long form and token form of the identifier, and MUST treat the two as equivalent if they do.

If the source of a message does not exist, and it is a KILL or SQUIT message, implementations MUST parse the message, treating the directly linked server from which the message came as the source; otherwise, the message MUST be ignored.

If the source of a message exists, but the message came from the wrong direction, implementations MUST ignore the message.

Registration and synchronization#

Server registration and authentication#

After a connection has been established, the initiator sends the PASS message as follows:

PASS :<password>

The password is compared with the password present in the listener's configuration file, and is used to confirm credentials after the SERVER message has been received, as shown below. Implementations MAY choose to perform additional verification, such as validating TLS certificates.

1      2            3          4          5          6          7                 8        9SERVER <servername> <hopcount> <boottime> <linktime> <protocol> <numeric/maxconn> [+flags] :<description>

Notes:

  1. The SERVER message, indicating this connection wants to introduce a new server to the network
  2. The name of the server being introduced
  3. The hop count of the server being introduced; this is always 1 when introducing yourself
  4. The epoch timestamp specifying when the ircd was started
  5. The epoch timestamp specifying when the server initiated the link to the network
  6. The protocol identifier for the server:
    • This parameter informs the network which protocol the server is compliant with, e.g., if it is a P10 compliant server, then the value of this parameter would be "P10"
    • If the server being introduced has not successfully synced its database with the network (i.e., completed its net.burst), then the value should be prefixed with a J instead of a P to indicate it is currently still joining the network
    • The value of this parameter should always be JXX when the server is introducing itself (e.g., J10)
  7. The numeric, and maximum connections identifier for this server:
    • This parameter is formatted exactly the same as a client numeric. The first two characters identify the server's numeric, whilst in this situation, the final three characters define the maximum number of clients that this server can hold (and more importantly, the maximum number of numerics it will generate). This is always one less than a power of two, since the server users it as a bitmask. A server can give out a higher numeric than this; however, it will be "ANDed" with this number to find its entry slot. This is done so that a server nearing the maximum number of clients can give out more numerics than it is using to prevent a new client getting a numeric that was used only seconds ago and possibly getting messages destined to the old user
    • As an example, a value of "AK]]]" would indicate that this server has the numeric 10, and will generate client numerics up to 262,143
  8. [optional] The flags parameter is used to indicate the server's type, and/or what capabilities it supports. If present, it MUST be prefixed with a +
    • The flags supported by ircd-yeti are:
      • h - indicates this server is a hub
      • s - indicates this server is a service
      • 6 - indicates this server supports IPv6
      • n - indicates this server supports parsing of opernames
  9. The final parameter is a textual description for the server prefixed by a colon

Example:

SERVER irc.example.org 1 1597451814 1597451828 J10 AKAP] +h6n :IRC server

Once the listener has verified the information, it will send its own PASS and SERVER messages. If the initiator's credentials were invalid, the listener SHOULD issue an SQUIT with a relevant reason.

Network database re-synchronization#

After the connection has been established and verified, the next step is to synchronize the database of server, ban, client and channel information between the two server. This is commonly referred to as the net.burst.

SERVER messages#

Server details are transmitted via SERVER messages, similar to the initial introduction message:

<prefix> S <servername> <hopcount> <boottime> <linktime> <protocol> <numeric/maxconn> [+flags] :<description>

The syntax of this message is nearly identical to the initially received server message; however, in this case the message is numeric prefixed, and the message identifier uses the token instead of long form name. The numeric prefix indicates which server sent this message, and therefore, which hub this new server is linked to.

GLINE / JUPE / SHUN messages#

All unexpired propagated Glines, Jupes and Shuns are transmitted via GLINE, JUPE and SHUN messages, respectively.

Each of these messages are described more in depth later in this specification.

NICK messages#

Client information for all known users is transmitted via NICK messages:

1        2 3      4          5           6          7      8                     9          10        11<prefix> N <nick> <hopcount> <timestamp> <username> <host> [+modes [parameters]] <base64ip> <numeric> :<realname>

Notes:

  1. The numeric of the server sending this message, thus owning this client
  2. The NICK token
  3. The nickname of this client
  4. The hop count of this client, i.e., how many servers away it is on
  5. The epoch timestamp indicating when this user last changed its nickname
  6. The client's username/ident
  7. The client real host
  8. [optional] The client's user modes. If present, this parameter is always prefixed with a +.
    • The +o usermode is followed by the client's opername, if opernames are supported
    • If the user is authenticated, the special +r usermode is sent followed by the client's account stamp, which is formatted as: accountname:account_timestamp:account_id:account_flags
    • If the user has a fakehost, the special +f usermode is sent followed by the client's fakehost
  9. The real IP address of the client, Base64 encoded
  10. The client's unique identifier in SSCCC format
  11. Free format real info line, also referred to as gecos

Example:

AK N ClientA 1 1597452760 ~user userhost.example.com +oiws opername B]AAAB AKAAA :realname

The NICK message may be possibly followed by AWAY, SWHOIS, PRIVS, CERTFP and/or FAKE messages.

BURST messages#

Channel details and membership information is synchronized in one (or more) BURST messages for each known channel. The first two parameters are always the channel name and timestamp. The other parameters are optional. Implementations MUST be able to parse modes, membership lists, and bans in any sequence.

1         2 3         4           5       6     7        8         9<numeric> B <channel> <timestamp> [+modes [key] [limit]] <members> [:%bans]

Notes:

  1. The numeric of the server sending this message
  2. The BURST token
  3. The name of channel to which this data belongs
  4. The epoch timestamp indicating when this channel was created
  5. [optional] Channel modes. If present, this parameter is always prefixed with a +
  6. [optional] Channel key. This parameter is present if the channel modes contain a "k" mode
  7. [optional] Channel limit. This parameter is present if the channel modes contain an "l" mode
  8. [optional] A comma separated list of client numerics (see formatting rules below)
  9. [optional] A space separated list of bans, ban exceptions, quiets, and invite exceptions present in the channel (see formatting rules below)

Numerics in the membership list parameter can have the following symbols appended to them: ":v", ":h", ":vh", ":o", ":vo", ":ho" and ":vho". These indicate chanop (o), halfop (h), voiced (v), or combination thereof. This state applies to the numeric it is attached to, and all subsequent numerics until another state is encountered.

For example, consider the following membership list:

AAABA,AAABB:v,AAABC,AAABD:h,AAABE:vo,AAABZ

Here, AAABA has no status in the channel. AAABB and AAABC are both voiced, while AAABD is halfopped, leaving AAABE and AAABZ as voiced and opped. As shown, in the example, users must be sorted as follows: users without modes, users with voice, users without halfop, users with op, users with halfop and voice, users with op and voice, and then finally users with op, halfop and voice.

If the BURST message contains a bans parameter, the first character of the parameter is a %, then a space separated list of bans. This parameter is also used to burst ban exceptions, quiets, and invite exceptions:

  • The first ban that begins with a ~ (without a mask of its own) indicates that the masks that follow are ban exceptions
  • The first ban that begins with a & (without a mask of its own) indicates that the masks that follow are quiets
  • The first ban that begins with a ^ (without a mask of its own) indicates that the masks that follow are invite exceptions

For example, consider a BURST message containing the following bans parameter:

:%*!*@pos1.example.com another!ban@pos2.example.com ~ *!fred@pos1.example.com & ^ $a:frank

Here, the following bans, ban exceptions and invite exceptions would be added to the channel:

While the & prefix is present in the above example, no masks followed it indicating there were no quiets. An implementation MAY choose to omit a prefix for ban exceptions, quiets, and/or invite exceptions, respectively, if such lists contain no masks. If the bans parameter is present, it MUST always be prefixed with %, even if it doesn't contain any bans.

If the length of a BURST message exceeds the maximum line length (512 characters) then the remaining channel members/bans are sent in subsequent BURST messages which are only used to add additional members or bans to the channel, if necessary. There will be no modes parameter present.

The BURST message may be possibly followed by TOPIC and/or CFEAT messages.

Channel TS rules#

If a BURST message is parsed, the timestamp is compared with the timestamp of the existing channel:

  • If the incoming timestamp is older than the existing timestamp, all modes, ops/halfops/voices, bans/ban exceptions/quiets/invite exceptions on the existing channel are cleared before adding the new items in the burst to the channel. The topic and invite list should be cleared as well.
  • If the existing timestamp is older than the incoming timestamp, all modes, ops/halfop/voices, bans/ban exceptions/quiets/invite exceptions from the burst are ignored and not propagated, only the membership list.
  • If the timestamps are equal, the modes, bans, etc. are merged. A mode that is set wins over a mode that is not set. If both the incoming and existing modes contain a limit/key, a lower limit wins, and a key that is first alphabetically wins.

Messages#

ACCEPT#

  • Token: AP
  • Source: server
  • Parameters: client numeric, mask(s)

Modifies a client's accept list.

ACCOUNT#

  • Token: AC
  • Source: server
  • Parameters: client numeric, account name, account timestamp, account ID, opt. account flags

The ACCOUNT message provides a way for servers, such as "services", to set account information that is associated with a client. Once set, implementations MUST NOT allow it to be cleared. A client's account flags MAY be changed only if all other parameters match the account information already set for the client.

During net bursts, a client's account information is propagated in the NICK message using the special user mode +r followed by the "account stamp".

An account name longer than ACCOUNTLEN, which is currently 30 characters in ircd-yeti, is a protocol violation and MUST NOT be applied to the client.

ADMIN#

  • Token: AD
  • Source: user
  • Parameters: hunted

Remote ADMIN request.

ASLL#

  • Token: LL
  • Source: user
  • Parameters: server mask, hunted

Remote Asymmetric Link Latency (AsLL) request.

AWAY#

  • Token: A
  • Source: user
  • Parameters: opt. away reason

Propagates away status of a client.

If the away reason is empty or not present, mark the client as not away; otherwise, mark the client as away.

Implementations MAY choose not to propagate a client's away reason when the client is changing the away reason from one non-empty string to another non-empty string.

CERTFP#

  • Token: CF
  • Source: server
  • Parameters: client numeric, fingerprint

The CERTFP message provides a way for servers to propagate the certificate fingerprint that is associated with a client.

CFEAT#

  • Token: CT
  • Source: user
  • Parameters: channel, timestamp, feature setting(s)

The CFEAT message is used to propagate channel feature settings for a channel. The first two parameters are always the channel name and timestamp. The other parameters contain space separated feature=value pairs.

Rules for generating a CFEAT message are as follows:

  • One or more feature=value pairs may be present
  • Features that allow values that contain spaces must be the last parameter

If a CFEAT message is parsed, the timestamp is compared with the timestamp of the existing channel. If the existing timestamp is older than the incoming timestamp, implementations MUST ignore and not propagate the message. Otherwise, the existing feature values are updated with the incoming values and propagated.

CHECK#

  • Token: CC
  • Source: user
  • Parameters: channel|user|servername

Remote CHECK request.

CLEARMODE#

  • Token: CM
  • Source: any
  • Parameters: channel, control string

The CLEARMODE message propagates a clear mode request for a channel.

Implementations SHOULD verify that the source has the necessary privileges to perform the action.

CLOAK#

  • Token: CK
  • Source: server
  • Parameters: mechanism name, key

The CLOAK message propagates a cloak key change for the specified cloaking mechanism.

CONNECT#

  • Token: CO
  • Source: any
  • Parameters: server to connect to, port number, hunted

Remote connect request. The port can be 0 to use the default port.

Implementations MAY verify connection rules and jupes.