Tip of the day: If you want to bypass access checks for channels as an IRCOp, use SAMODE or SAJOIN. Or use OperOverride.

Server protocol:Changes

From UnrealIRCd documentation wiki
Jump to navigation Jump to search

Below we outline the changes in the server-to-server (S2S) protocol between UnrealIRCd versions.

UnrealIRCd 6.0.0+


  • Server to server lines can now be 16384 bytes in size when PROTOCTL BIGLINES is set. This will allow us to do things more efficiently and possibly raise some other limits in the future. This 16k is the size of the complete line, including sender, message tags, content and \r\n. Also, in server-to-server traffic we now allow 30 parameters (MAXPARA*2).
    The original input size limits for non-servers remain the same: the complete line can be 4k+512, with the non-mtag portion limit set at 512 bytes (including \r\n), and MAXPARA is still 15 as well.
  • In command handlers, individual parv[] elements can be 510 bytes max, even if they add up like parv[1] and parv[2] both being 510 bytes each. If you need more than that, then you need to set the flag CMD_BIGLINES in CommandAdd(), then an individual parameter can be near ~16k. This is so, because a lot of the code does not expect parameters bigger than 512 bytes (but can still handle the total of parameters being greater than 512). The new flag allows gradually opting in commands to allow bigger parameters, after such code has been checked and modified to handle it.


  • Allow services to send a couple of protocol messages in the unregistered / SASL stage. These are: CHGHOST, CHGIDENT and SREPLY
    • This allows services to set the vhost on a user during SASL, so the user receives the vhost straight from the start, before all the auto-joining/re-rejoining of channels.
    • Future anope/atheme/etc services will presumably support this.


  • Previously some server protocol commands could only be used by services, commands such as SVSJOIN and SVSPART. We now allow SVS* command to be used by any servers, so the JSON-RPC API can use them. There's a new option set::limit-svscmds so one can revert back to the original situation, if needed.


  • The creationtime is now communicated of users. Until now this information was only known locally (the thing that was communicated that came close was "last nick change" but that is not the same). This is synced via (early) moddata across servers. Module coders can use get_connected_time().
  • The SVSO command is back, so services can make people IRCOp again. See HELPOP SVSO or the commit for more information.

UnrealIRCd 5.x to UnrealIRCd 6.0.0

This is a copy-paste from the relevant part of the release notes:

Server protocol
* When multiple related `SJOIN` messages are generated for the same channel
  then we now only send the current channel modes (eg `+sntk key`) in the
  first SJOIN and not in the other ones as they are unneeded for the
  immediate followup SJOINs, they waste unnecessary bytes and CPU.
  Such messages may be generated when syncing a channel that has dozens
  of users and/or bans/exempts/invexes. Ideally this should not need any
  changes in other software, since we already supported such messages in the
  past and code for handling it exists way back to 3.2.x, but you better
  check to be sure!
* If you send `PROTOCTL NEXTBANS` then you will receive extended bans
  with Named EXTended BANs instead of letters (eg: `+b ~account:xyz`),
  otherwise you receive them with letters (eg: `+b ~a:xyz`).
* Some ModData of users is (also) communicated in the `UID` message while
  syncing using a message tag that only appears in server-to-server traffic,
  `s2s-md/moddataname=value`. Thus, data such as operinfo, tls cipher,
  geoip, certfp, sasl and webirc is communicated at the same time as when
  a remote connection is added.
  This makes it that a "connecting from" server notice can include all this
  information and also so code can make an immediate decission on what to do
  with the user in hooks. ModData modules need to set
  `mreq.sync = MODDATA_SYNC_EARLY;` if they want this.
  Servers of course need to enable `MTAGS` in PROTOCTL to see this.
* The `SLOG` command is used to broadcast logging messages. This is done
  for log::destination remote, as used in doc/conf/snomasks.default.conf,
  for example for link errors, oper ups, flood messages, etc.
  It also includes all JSON data in a message tag when `PROTOCTL MTAGS` is used.
* Bounced modes are gone: these were MODEs that started with a `&` which
  servers were to act on with reversed logic (add becoming remove and
  vice versa) and never to send something back to that server.
  In practice this was almost never used and complicated the code (way)
  too much.

UnrealIRCd 4.x to UnrealIRCd 5.0.0

These are the server protocol changes between UnrealIRCd 4.x and 5.0.0 stable.

Required options

UnrealIRCd 5 now assumes you support the following PROTOCTL options: NOQUIT EAUTH SID NICKv2 SJOIN SJ3 NICKIP TKLEXT2.

If you fail to use SID or EAUTH then you will receive an error. For the other options, support is assumed, no warning or error is shown when you lack support.

Fortunately these are options that most, if not all, services already support since UnrealIRCd 4.x so it shouldn't be a problem and shouldn't even need any changes for UnrealIRCd 5.

For more information about why this change was implemented, see FAQ#old-server-protocol

New optional options

  • PROTOCTL MTAGS indicates that the server is capable of handling message tags and that the server can cope with 4K lines. (Note that the ordinary non-message-tag part is still limited to 512 bytes).

Other changes

  • Pseudo-ID support in SASL was removed. We now use real UID's. This can break services. For example anope had fixes added and requires 2.0.7 on an UnrealIRCd 5 network.

UnrealIRCd 3.2.x to UnrealIRCd 4.0.0

Below are the server protocol changes between UnrealIRCd 3.2.x an UnrealIRCd 4.0.0 stable. Note that these changes were made more than 5 years ago! It is only kept for historic purposes.

All traffic we discuss below is server-to-server traffic. At no point we expose such traffic to regular clients (eg: the use of UID's).

Removed features

The following features were removed in UnrealIRCd 4

SJB64 (Base64 timestamps)

This feature was removed because it only saves a few bytes of bandwidth per line at a cost of complicating the code too much.

ZIP (Zip links)

This feature was removed when the I/O engine was rewritten. It may or may not be re-introduced at a later point.

NS (Server numerics)

Server numerics have been removed but have been replaced by SID's (see next section)

New features

These are new features that you can choose to enable (or not).

SID (Server and nick id's)


Server id's (SID's) work very similar to the removed server numerics feature and consist of 3 alphanumerical characters which uniquely identify a server (where the first character is always a digit). No base64 encoding involved. You can (theoretically) use a SID anywhere a server name is used, like:

:server.name NOTICE #chan :Hello

Can become:

:001 NOTICE #chan :Hello

SID command

When a server links in you now receive a "SID" rather than a "SERVER" command. Refer to the Server ID page for more information.


When you enable SID you also get user id's (UID's). UID's consist of alphanumerical characters and can (not must!) theoretically be used at any place where you use a nick name. The first 3 characters identify the SID of the server where the user is on (this is part of the UID) and thus a UID will always start with a digit.

The benefit of using UID's is that it really uniquely identifies a user regardless of the current nick name. This allows us to solve some long-standing problems where nick collisions and race conditions cause desynchs such as 'ghosts' in a channel.


:One NOTICE Two :Hi there

Can become:


As you can see, it doesn't necessarily shorten the length. That isn't the purpose of UID. The benefit of UID is the uniqueness described earlier.

UID command

Instead of "NICK" protocol messages you will receive "UID". See also:


If you want to support SID's and UID's then we suggest:

  • store the SID & UID in your server & client structs
  • make functions like find_person() also search this field. UID's and SID's just look like regular names after all, except they start with a digit
  • ensure you handle the SID and UID commands
  • send SID in PROTOCTL to indicate your software supports SID & UID