This site is deprecated; docs have moved to!

Historical:InspIRCd Spanning Tree (1.1)

From the makers of InspIRCd.
Revision as of 02:05, 5 November 2006 by Special (Talk | contribs)

Jump to: navigation, search

This page will be expanded as we add to the protocol. Protocol changes will be generally backwards-compatible with previous versions (up to a point).

Linking a server into an InspIRCd spanning tree is relatively straightforward for anyone who's handled irc servers and their protocols before. To connect to a server (which has our details in a <link> tag) we first proceed with the authentication phase, as detailed in the section below.

The Authentication Phase

During the authentication phase, a three-way handshake is performed where both servers exchange their passwords. Unlike most ircds (the notable exception being ircu) this must be done in lock-step fashion, e.g. one server sends a request then waits for the other server to reply before sending another. Note that once the authentication phase is complete, the data flow moves to being full duplex and no such restrictions apply once the BURST command is received (see below).

Step One - Connection

Server A, wishing to connect to the network, connects to server B using connect() or equivalent. When the connection is established, it immediately sends the SERVER command (see the commands list below) to server B which is waiting for inbound connections. Up until this point, server B will do nothing but accept the connection.

Step Two - Inbound Authentication

Server B, after receiving server A's SERVER command, analyzes the parameters (namely server name and password) and if it is not happy with the credentials, should instantly send a suitable ERROR reply, and close its connection. However, if server B deems the credentials correct for server A, server B then sends its own SERVER command, with its own credentials in to authenticate to server A.

Step Three - Outbound Authentication

Server A, upon receiving server B's credentials, analyzes them (again, namely the server name and password), and again, if it is not happy, it can send an ERROR reply, and close its connection. If the details are correct however, server A now sends a BURST command (see the commands list below) and begins its network burst.

Step Four - Network Burst

Upon receiving server A's network burst, server B also sends its own network burst, preceeded again by the BURST command. When both servers have finished bursting, they send the ENDBURST command. BURST and ENDBURST are only sent for local bursts.

The order which data is sent during the burst is important, and should be:

  • Firstly, the names of any servers connected to this one, directly or otherwise, with relative hop counts, 1 being a direct connection (these will be re-calculated by the receiving side)
  • Secondly, the nicknames of any users, sent using NICK, their OPERTYPE if they are an oper, and their channel list using FJOIN (see the commands list, below)
  • Thirdly, the modes (Sent using FMODE), topics (sent using FTOPIC) and bans (sent again using FMODE) for each channel in turn (no specific order of channels).
  • Lastly, any module specific data (which may be a combination of FMODE and any other module-specific commands).

Example Authentication Phase

This is an example of a successful authentication:

>> SERVER password 0 :Description here
<< SERVER password 0 :ChatSpike InspIRCd test server

(both servers now operate in duplex mode sending data freely)

Command List

This section documents all valid server to server commands which are specific to InspIRCd. Most commands are similar or identical to RFC1459 to make adding support to other programs (such as services packages) straightforward. Where commands are not documented here, they are transmitted across the spanning tree in standard form:

:<nickname> COMMAND <parameters>

For example:

:Brain PRIVMSG #chatspike :Moo moo!


:Craig MODE #chatspike +ov Brain Brain

Where commands are part of the RFC, but their behaviour or their syntax is different, the commands are documented here in their InspIRCd form.

Modular commands

Any module which implements a command, for example SAJOIN, will have those commands automatically passed out onto the network as a broadcast. Any servers which also have this module loaded and handling the same command will be informed of the inbound command coming in off the network. If a server does not recognise a command, it should close the connection immediately to prevent a desync. This ensures transparent operation of modules on the spanning tree, independent of what tasks these modules perform. To load a module network wide, configuration files should be edited then then the modules introduced via /rehash *. Examples of such modular commands are SAJOIN, SAPART, KNOCK, REMOVE, PARK.


(Broadcast, One-To-One)

SERVER <servername> <password> <hopcount> :<description>

The SERVER command is used to authenticate to the network, or to introduce a new server, once authenticated. The two forms of this command are as follows:

SERVER <servername> <password> 0 :<description>

This version of the command is used when authenticating (see the authentication phase, above). The password must be supplied and must be valid on the remote server, and the hopcount must be zero otherwise an ERROR should be generated by the remote side.

:<local server> SERVER <remote server> * <distance> :<description>

This version of the command is used after authentication (during bursting and normal operation) to indicate a new server has been introduced. This command will be passed on to all other servers. The password field contains a * as it is unused. The distance field must be one or greater, indicating a non-local connection. The actual value is not important so long as it is greater than zero, as the hopcounts are relative and re-calculated by the recipient to match their local view of the server map.



:<server> FJOIN <channel> <timestamp> :<[prefixes],nickname> {<[prefixes],nickname>}

This command is used within a netburst to syncronize all of the users on a channel, and set their permissions upon that channel. Channel restrictions on remote users who are sent in FJOIN or JOIN should be ignored to prevent desyncs, e.g. bans, invite exceptions, keys and invite-only status should not be checked. For example: FJOIN #staff 1133630884 :@%,Brain @,Craig %,Dune +,Azhrarn w00t Elf

Note that the modes built from this should be merged then sent only to local clients, for example, the above FJOIN will queue and send the mode change to be sent after the clients are joined to the channel: MODE #staff +ohohv Brain Brain Craig Dune Azhrarn

The timestamp is used to determine which modes are the established modes upon the channel. To prevent splitriding, the losing side (with the highest timestamp) first removes all status modes (+qaohv) from all users upon the channel, then updates its timestamp to match the timestamp of the winning side, after which all modes from the winning side are accepted. The winning side will then deny all mode changes from the losing side.

The losing side should 'echo' out all mode removals as FMODE, so that all other servers are aware of the privilage modes being cleared.

For example, if server A sends this:

:server.a FJOIN #staff 1230 :@,Brain @,Craig

and server B sends this:

:server.b FJOIN #staff 1234 :@,ol typobox43

Then when server A receives the FJOIN from server B, it will deny giving ol ops, and server B will remove ops from ol, echoing out the following line:

:server.b FMODE #staff 1230 -o ol

Doing things this way around means that it is not possible for a server to ignore its settings and allow netjoin abuse to occur. Note that the TS is updated before the FMODE lines are echoed, so that they are accepted by the rest of the network including the winning server.

NB: In the current implementation, if one server has the channel empty, it will emulate an extremely high local timestamp on the empty channel (20 seconds ahead of current time) so that all mode changes will be automatically allowed by the remote server and will not be bounced. When a user is the first user in the channel, the current implementation will send an FJOIN instead of a JOIN to specify clearly that by joining the channel the user has been given ops. This is done for compatibility with services packages.

In the 1.1.x implementation, all other modes must be passed through FMODE, therefore they are checked against timestamps anyway and this situation is prevented. The limit of 12 users per FJOIN is lifted due to the fact all the users are encapsulated in the last parameter of the command. This implementation of InspIRCd will still wrap the line at 460-NICKMAX characters however to ensure compatibility with services packages. The 1.1.x implementation may receive multiple modes per user (in no defined order), and these modes may be core or module implemented prefixes, including the defaults of @+ and optionally %. The prefixes and the nickname for each user are seperated with a comma (,) and if the user has no prefixes associated with them, the prefix field is empty and the section starts with a comma, e.g. ",nickname". For example: FJOIN #smelly 12345 :@%,whifty %,stinky +,larry ,moe +^,herbert

If a server ever receives a prefix which it does not recognise, for example the ^ symbol in the example above, it should immediately close the connection (after sending an ERROR message) to prevent a desync. This situation indicates that modules are not configured identically on both sides of the network, and continuing to link the servers could cause problems.


(Broadcast, special (see notes))

:<server name> REMSTATUS <channel>

The REMSTATUS command, when sent, causes all status modes to be removed from all users on the given channel immediately. The receiving server should convert the REMSTATUS command into a group of FMODE and MODE lines (FMODE between servers, server MODE between server and client) and send them out, cancelling any status modes. Status modes are modes (usually with prefixes, but not always) which give permissions to users on channels. Currently, this is the modes +ov, +h (where enabled) and +aq (where loaded).

Note that the REMSTATUS command itself should not be propogated to other servers -- instead, the receiving server should propogate the FMODE commands the REMSTATUS command causes.

NB: REMSTATUS will NOT lower (or change) the TS of the channel! If you want to do this, you must send an FJOIN first with a lower TS value.



:<source server or nickname> FMODE <target> <timestamp> <modes and parameters>

This command is used within a netburst (or sometimes after the burst) to syncronize modes on channels and users. For example: FMODE #opers 115432135 +bb *[email protected] *[email protected]

The timestamp determines wether the mode is allowed by the receiving server, or bounced. The rules for bouncing of modes are shown in the section below.

1.1 series servers should use FMODE for all mode changes where possible. It is sometimes not possible (e.g. when sending a mode change from a user origin) to use FMODE, as the TS merging rules could prevent parameterized modes such as +l from being set.

Mode-bouncing and FMODE TS rules

The rules for bouncing and merging modes in FMODE are as follows:

  • If the timestamp given in an FMODE is equal for both sending and receiving servers, the modes of both servers should be merged. This is done using the following algorithm:
  • Modes being added without parameters are always accepted by both sides, building a complete set of both sets of modes
  • Modes which have a parameter, but are not listmodes (e.g. not +o or +v) which are being added are merged based upon rules dependent on each mode letter. For example, the highest channel limit is accepted and the lower channel limit bounced, and the alphabetically later channel key accepted where the alphabetically earlier channel key bounced. The rules for this are fully documented below:
  • +k (core): Highest value wins, alphabetically (case sensitive)
  • +l (core): Highest value wins, numerically
  • +L (module): Highest value wins, alphabetically
  • +f (module): Highest value wins, case sensitive ASCII comparison
  • +J (module): Highest value wins, numerically
  • +j (module): Highest value wins, case sensitive ASCII comparison
  • Modes being subtracted are always allowed, regardless of their parameters, as there are no restrictions on the removal of modes and therefore no desync can occur from doing this.
  • Modules which implement modes will implement their own rulesets for their parameterized modes to determine which parameter wins when these modes are being added.
  • Modes which have been 'rejected' should be bounced back to their sending server using an FMODE with a server origin and the winning server's timestamp and parameter. Only the winning server is allowed to reject a mode character ('winning' is determined as stated above, via mode letter specific rulesets). These 'rejected' modes should not be unset, rather 'enforced'. So for example, if two servers have the timestamp '10', and server.a sends '+ntl 10' to server.b, and server.b already has the modes '+ntl 15' set, rather than sending '-l' back to server.a, server.b should send '+l 15' to server.a, so that then both servers remain synchronized.
  • If the timestamp given in an FMODE is higher than that of the receiving server, the receiving server will bounce the mode change back, using its own timestamp in the bounce, and forcing the mode to be unset. This prevents modehacking during desyncs and net merges. If the timestamp given in an FMODE is equal to, or less than that of the sending server, the receiving server will accept the mode without any bounce. When modes are bounced, the winning server is responsible for bouncing the modes of the losing server. It should examine each mode in turn and check wether it is applied on the winning server already. If it is, to avoid a desync the winning server should "reinforce" this mode by sending it back as set, otherwise if the mode is not set, it should be "inverted" (bounced) back at the source, unset. For example, imagine in the following scenario for a fictional channel #sprockets, for which server.a has modes "+ntlL 10 #chan1" and the lower TS of 1163355, and 'wins' against an FMODE sent to it from server.b, containing "-ntl+Lim #foo" with a TS of 1164466. The modes bounced back to server.b by server.a should therefore be:
:server.a FMODE #sprockets 1163355 +ntlL-im 10 #chan1
  • If the timestamp given in FMODE is lower than that of the receiving server, all modes should be accepted verbatim, but no TS modification should occur.

Exceptions to the rules

  • There is one exception to this rule: If a U-Lined server sends an FMODE and the timestamp is higher than that of the receiving server, the FMODE will be accepted (Although, the receiving server will complain loudly to its opers) under the assumption that the U-line is always overriding and correct in all circumstances and that our clock is probably just incorrect.
  • When bouncing a mode sent by a user, the bounced modes must originate from the winning server, not from any user. e.g. use a server 'origin' at all times to bounce mode changes.
  • Please note that if the clocks on your servers are completely desynched, you could end up with servers fighting over mode changes. This is why it is imperative to keep your clocks synched correctly at all times.
  • Please note that to prevent desyncs there is no checking of channel keys between servers or remote users. A channel key can be set whilst another key is already in place, or removed without providing the correct key. Some form of parameter must still be provided, however. To summarize; if server.a has the key "foo", server.b could send "FMODE #channel -k bar" and this would still be accepted and the key removed.



:<local server> SQUIT <remote server> :<reason>

This command indicates that server <remote server> has disconnected from <local server> with the given reason. When servers receive this command they must update their server maps accordingly, removing any users which existed upon the orphaned section of network. Seperate QUIT messages will not and should not be sent out for the exited users.



:<server/nickname> FTOPIC <channel> <time-set> <set-by> :<topic>

This command is used during a network burst to syncronize the channel topics. When setting a topic, the newest topic (highest time-set value) is set and the other discarded. The time-set value is a unix epoch time.



BURST {timestamp}

This command indicates the start of the network burst. It should only be sent when the network burst is local to indicate the end of the authentication phase (See above). If a timestamp is given, the local server must match their timestamp against that of the remote server, aborting if the delta between the two is greater than ten minutes (> 600 secs or < -600 secs).




This command indicates the end of the network burst. this should always be sent at the end of a network burst. The receiving server should usually apply z/k/q/g lines upon receipt of the ENDBURST command, rather than as it receives each one, saving on cpu time.



:<nickname> OPERTYPE <type name>

This command indicates that the specified user is an IRC operator of the given type. The <type name> given should exist in the configurations of all servers on the network for the oper status to propogate. If oper status does not propogate, desyncs can occur. Please note that InspIRCd does not let users or remote servers set the +o usermode under any circumstances. Sending OPERTYPE successfully places the +o usermode upon the given user as well as setting their oper type, so should be used to 'oper up' clients. The exception to this is u-lined servers, as u-lines are a core feature (there is no easy way around doing this) which permit all users with that server name in their record special abilities which negate the need for the +o flag.



:<local server> REHASH <remote server>

This command indicates that all servers matching the given <remote server> mask should immediately rehash their config files. This command is broadcast, meaning that all servers will receive and act upon it.



:<local server> NICK <timestamp> <nick> <hostname> <displayed-hostname> <ident> +<modes> <ip> :<gecos>
:<old nick> NICK <new nick>

The first version of this command introduces a new client into the network. If there is a nickname collision, the remote server you send the NICK command to is responsible for generating a KILL message and sending it back to you. The ip field is in dotted decimal form, e.g.

The second version of this command changes an existing user's nickname, as in the RFC.



:<nickname> JOIN <#channel>{,<#channel>} <timestamp>

The JOIN command has a timestamp attached to it, so that in case of a desync, servers may still determine the timestamp value for a channel. Consider the situation where a user leaves a channel on one server, at the same time a join is sent from a second - This version of JOIN prevents the timestamp being lost.



The RFC1459 command "USER" is not implemented by InspIRCd between servers, as this functionality is handled by the 8-parameter version of the NICK message.


(Broadcast, One-To-One)

:<source server> VERSION :<arbitary version string>

Whereas the RFC version of this command (no pun intended) requires that each time a user requests a remote server version, the server should direct a version request at a local server and wait for a reply, the InspIRCd version of this command operates differently. To save on cross-network bandwidth, instead, the InspIRCd protocol requires that this be sent as part of the network burst. All servers then cache the version strings of all other connected servers and may return them to clients without making any requests to the network. Servers may also update their version strings at any point after the burst.



:<nickname> FHOST <new displayed host>

The FHOST command is sent out when a server changes the displayed host of a user local to that server.



:<nickname> FNAME :<new GECOS field>

The FNAME command is sent out when a server changes the GECOS (full name) field of a user local to that server.



:<source server> ADDLINE [Q|Z|E|G] <mask> <setter> 

The ADDLINE command is used to (silently) set a GLINE, ZLINE, ELINE or QLINE. Whereas the GLINE, ZLINE, ELINE and QLINE commands can only be sent from a user source, and require that user to be online, ADDLINE may only be sent by a server (with a valid server name as the source), and the setter can be any arbitary text up to 64 characters in length (so it may be a nick which is not online, or a server name). Servers must use this command to sync Q, Z, E and G lines during a burst. After that point, users may add (or remove) G, Z, E and Q lines using the GLINE, ZLINE, ELINE and QLINE commands as documented below. The duration for ADDLINE may only be represented in seconds, and not the more complex form as shown for the other *LINE commands.



:<source nickname> GLINE <[email protected]> <duration> :<reason>
:<source nickname> GLINE <[email protected]>

This command sets or removes a GLINE (the first syntax given is to add, the second to remove) and is passed on to servers exactly as it is formatted in our client Commands guide. The duration in this command may be formatted in the form: 1y2w3d4h5m6s which means 1 year, 2 weeks, 4 hours, 5 minutes 6 seconds, or simply as a number of seconds (as in ADDLINE)



:<source nickname> ELINE <[email protected]> <duration> :<reason>
:<source nickname> ELINE <[email protected]>

This command sets or removes a ELINE (the first syntax given is to add, the second to remove) and is passed on to servers exactly as it is formatted in our client Commands guide. The duration in this command may be formatted in the form: 1y2w3d4h5m6s which means 1 year, 2 weeks, 4 hours, 5 minutes 6 seconds, or simply as a number of seconds (as in ADDLINE)



:<source nickname> ZLINE <ipmask> <duration> :<reason>
:<source nickname> ZLINE <ipmask>

This command sets or removes a ZLINE (the first syntax given is to add, the second to remove) and is passed on to servers exactly as it is formatted in our client Commands guide. The duration in this command may be formatted in the form: 1y2w3d4h5m6s which means 1 year, 2 weeks, 4 hours, 5 minutes 6 seconds, or simply as a number of seconds (as in ADDLINE)



:<source nickname> QLINE <nickmask> <duration> :<reason>
:<source nickname> QLINE <nickmask>

This command sets or removes a QLINE (the first syntax given is to add, the second to remove) and is passed on to servers exactly as it is formatted in our client Commands guide. The duration in this command may be formatted in the form: 1y2w3d4h5m6s which means 1 year, 2 weeks, 4 hours, 5 minutes 6 seconds, or simply as a number of seconds (as in ADDLINE)



:<source nickname> SVSHOLD <nickname> <duration> :<reason>
:<source nickname> SVSHOLD <nickname>

This command sets or removes a SVSHOLD (the first syntax given is to add, the second to remove). The duration in this command may be formatted in the form: 1y2w3d4h5m6s which means 1 year, 2 weeks, 4 hours, 5 minutes 6 seconds, or simply as a number of seconds.

An SVSHOLD is virtually equivilant to a Q:Line, except that it is generally controlled by services, and is held seperate from Q:Lines. Commonly used for Services enforcers.

NOTE: Requires to be loaded.



:<source server> SVSNICK <old nick> <new nick> <timestamp>

This command is implemented for services compatibility. When given it will change the user <old nick>'s nick to have the nickname <new nick>. Unlike many other implementations this command may be issued by any server (not just a U-Lined server). The client's timestamp value will be reset to the timestamp given in the SVSNICK command. USE WITH CAUTION! There is purposefully no client-side version of SVSNICK for opers, the SANICK module must be used instead for opers to change user nicks, which does not change the user's timestamp. This command is never sent out by InspIRCd servers directly, however it is forwarded from services servers, and should therefore be supported.

PLEASE NOTE: When using this command, it does not in itself force a nickchange at each server directly that it passes through. The server where the old nickname resides is the only server to directly act upon the SVSNICK, and does so by echoing back a NICK to the rest of the network 'acknowledging' the nickchange. Any other servers where the old nick is not a local user will just pass the SVSNICK on, so long as the old nick exists. This allows for services servers to wait for confirmation that the user changed nick, or collided, before actually introducing enforcers.



:<source server> SVSJOIN <nick> <channel>

This command is implemented for services compatibility. When given it will force the given nick to join the given channel. Unlike many other implementations this command may be issued by any server (not just a U-Lined server) but there is purposefully no client-side version for opers, the SAJOIN module must be used instead for opers to force users to join channels. This command is never sent out by InspIRCd servers directly, however it is forwarded from services servers, and should therefore be supported.



:<source nick> SVSMODE <nick> <channel>

This command is implemented for services compatibility. When given it will allow modes to be set on users which are on remote servers, bypassing client-side checks. Unlike many other implementations this command may be issued by any server (not just a U-Lined server) but there is purposefully no client-side version for opers, the SAMODE module must be used instead for opers to force user or channel MODEs. This command is never sent out by InspIRCd servers directly, however it is forwarded from services servers, and should therefore be supported.



:<source server> METADATA <channel|user> <key> :<value>

Because InspIRCd is completely modular, modules require a way of passing messages from server to server, transparent of the actual protocol in use, without two modules competing over resources. To accomplish this, InspIRCd allows modules to extend user and channel 'records' in the ircd itself with arbitary data, known as metadata (in InspIRCd API terms, this is known as the Extensible class). Each extra piece of data is named uniquely using an ASCII key, and each module only modifies its own keys and values. The internal format of this data is module specific.

When two servers sync, the protocol module,, retrieves the list of metadata names for each user or channel as it is synched, and then queries all modules, asking them to submit an ASCII string that represents the given key's metadata. This is then sent to the opposite side of the netburst. The opposite end, upon receiving this metadata, again queries all modules, until one claims it and re-assembles the ASCII <value> field back into its native form, and stores it in the key for that particular user or channel.

Most non-InspIRCd systems can safely ignore METADATA commands (and should do so!), and should NOT send any without knowing exactly which module uses the given key, and what for, and the format of their ASCII data. Please note that the <value> field only has to be meaningful to the module which generated the message, and may not be usable in any other form (e.g. it may be encrypted or otherwise munged).



:<source nick> IDLE <target nick>
:<source nick> IDLE <target nick> <signon> <seconds idle>

When a user issues a remote WHOIS, the IDLE command (in its first form listed above) is sent out. The user issuing the WHOIS is placed into the <source nick> field and the user being whois'ed is placed into the <target nick> field. The WHOIS response is then locally delayed, until a remote server responds via the second format of the command. The user they whois'ed is placed in the <source nick> field, and the user that issued the WHOIS is placed in the <target nick> field, along with the signon time and idle time of the source nickname. Once the original server receives this information, it is able to then build its entire WHOIS response and send it to the originating user.



:<source server> PUSH <target nick> :<any text>

The PUSH command, when sent, will be passed to the server where <target nick> resides, and then the arbitary text contained within <any text> will be dumped to the user's file descriptor. This may be used as an encapsulation mechanism for sending raw lines to users and implementing systems in InspIRCd which the protocol does not directly support.



:<source server> TIME <target server> <issuing nick>
:<source server> TIME <target server> <issuing nick> <timestamp>

The TIME command is a more efficient version of the TIME command and numeric used by other ircds. The first form of the command is used to request the time of remote server <target server> on behalf of <issuing nick>. When the remote server replies to the request it should use the second form of the command, which has the timestamp appended, and <target server> and <source server> transposed so that the message finds its way back to the issuer. Once the issuer receives the response they should decode the timestamp using localtime() and asctime() and display it to the user given by <issuing nick> in the same manner as a local TIME request.



:<source server> TIMESET <timestamp>
:<source server> TIMESET <timestamp> FORCE

The TIMESET command is used for time synchronization between servers; unless disabled, servers will send a TIMESET every 12 hours and the lowest timestamp on the network will be adopted by all servers. The 'FORCE' parameter (case sensitive) can be added to force your timestamp to be used by all servers. Time is also synchronized with the BURST command.



AES <server name>

Upon connection, servers which are of version 1.0 RC1 or later may negotiate optional AES encryption. When doing so, the connecting server will send this command before the SERVER and BURST command, but after any CAPAB commands (see below) and any commands following the AES command (including the SERVER command and the netburst) will be encrypted using AES, wrapping each encrypted line in base64 before transit. Both ends of the connection are expected to have a shared private key which is used to encrypt and decrypt the session. If the session cannot be decrypted, no authenticated connection can be made.

It is possible to send the AES message after negotiation of the server link, however this is not supported by current versions of InspIRCd. If the AES message is sent more than once in a single session, the second (and any other) AES commands will be dropped and an error given.

Encryption strengths of 128, 192 and 256 bits are currently allowed, using key lengths of 16, 24 or 32 bytes respectively with the CBC cipher.

WARNING: While in AES mode, lines sent over the link may exceed 512 bytes! Because messages must be padded to the nearest block size, where a block is equal to the key size, the encrypted payload may be up to 543 characters in length (512 plus the maximum modulus of 31 for the largest permitted key length). Also, the base64 encoded payload, which wraps the encrypted payload will further increase its size by up to 20%, making messages be as long as potentially 750 bytes! Because InspIRCd itself uses the C++ std::string class, the actual length of the message is not important as a buffer overflow cannot occur in any practical situation.

When the connect is running in AES encrypted mode, a certain subset of commands may be allowed along the link unencrypted so that the network is still able to understand them in the event of an encryption failure. Currently, the most recent version of InspIRCd only allows the ERROR command to pass along the link in this manner.



CAPAB MODULES <module list>

The capab command, if sent, must be sent in the authentication phase before any other command (including the optional AES command. If the server is listening for connections, then it must immediately send out this command as its 'banner'.

Any server which does not understand the CAPAB command should silently ignore all CAPAB commands and their parameters.


CAPAB START will cause the capaibility list to be cleared ready for negotiation. This is optional when first connecting, but if you wish to re-negotiate CAPAB after you have connected, you must first use CAPAB START.


CAPAB MODULES should contain a comma seperated list of modules in alphabetical order. Because some services packages limit the line length to 512 bytes, this should wrap at 509 bytes and continue the list in further CAPAB MODULES messages if the list is too long to fit onto one line. Module names are case sensitive. To build this list, InspIRCd servers make a list of all modules with the VF_COMMON flag set in their version information, and sort it alphabetically, seperating each module name with commas. As windows builds of InspIRCd also use .so as the file extension for modules, this will not effect linking to versions of InspIRCd running on windows, or other non-unix platforms, so long as naming conventions are adhered to.


CAPAB CAPABILITIES should contain a space seperated list of variables and values in its single parameter. As with CAPAB MODULES, if its length goes over 509 bytes it should wrap and add further values into a second or third (etc) CAPAB CAPABILITIES line. In a CAPAB CAPABILITIES entry, the value cannot contain spaces and the variable name should not be duplicated more than once in the list. Variable names and values are both case sensitive.


The following variables are recognised by InspIRCd 1.1:

PROTOCOLYesThe current protocol version.
NICKMAXYesMaximum length of nicknames including \0
HALFOPNoServer supports halfop when defined and set to 1
CHANMAXYesMaximum length of channel names including \0
MAXMODESYesMaximum number of parameterized modes per MODE command
IDENTMAXYesMaximum length of ident including "~" symbol and \0
MAXQUITYesMaximum length of quitmessage including \0
MAXTOPICYesMaximum length of channel topics including \0
MAXKICKYesMaximum length of channel kick message including \0
MAXGECOSYesMaximum length of full name field (GECOS)
MAXAWAYYesMaximum length of away messages including \0
IP6NATIVENoIf this is set, IP6SUPPORT will exist and be set. Signifies this server is IPV6 native
IP6SUPPORTNoIf this is set, this server can handle users, bans etc which are in IPV6 form


Upon receiving CAPAB END, the server should compare its values and lists to check they match appropriately. If they do not, an error will be generated and the connection closed.

Example CAPAB output

This is example output of CAPAB in 1.1:




:<source server> PING <destination-data>
:<source server> PONG <destination-data>
:<source> PING <source server> :<destination server>
:<source> PONG <source server> :<destination server>

The PING command is implemented in two forms. The two-parameter version of PING is identical to RFC 1459, and you should refer to RFC 1459 and RFC 2813 for more information on this command. This format of the PING (and PONG) command can traverse servers and can be used for latency and end-of-burst checks. The short form of the command with one parameter is InspIRCd-specific. If you receive a PING command with one parameter, you must answer with a PONG on the same connection the PING came from. the contents of the PONG reply are not important, however most InspIRCd servers populate this field with the target server name. If you do not reply to the one-parameter PING with a one-parameter PONG within two minutes, the remote server should close your connection.

NB: The short-form of PING with one parameter can NEVER travel more than one server away from its source. It should only be used for local 'liveliness' checks on the connection.

Message Routing

InspIRCd has four behaviours when it routes a message. These four behaviours are chosen dependent upon the message and the target and source of that message individually. These behaviours are:

One to One routing

This is used to route a message from one server directly to another server, taking a route only through servers which need to process the message in order to pass it straight to its destination. Examples of this are PRIVMSG and NOTICE direct to a user (not to a channel) and any messages exchanged during the initial burst and authentication phase.


One to all (Broadcast)

This is used to broadcast a message to all servers, and each server which receives such a message will then pass it on to its peers using "one to all-but-one" as shown below. This is used for messages which the entire network must see to remain synchronized, e.g. NICK and QUIT.


One to all-but-one

This is used to pass on a "one to all" message which has originated from another server. The message may not be passed on via a second "one to all" message, because doing so would bounce the message back along the network to its source and cause a desync.


One to group

This is used only by channel PRIVMSG and NOTICE. To cut down on bandwidth, channel PRIVMSG and NOTICE are not broadcast. To achieve routing for these types of message, a list is compiled consisting only of locally connected servers the PRIVMSG or NOTICE must be sent to in order to reach all of its recipients. Each recipient is then responsible for running the message against this algorithm again to ensure it eventually reaches all intended recipients, and no extra servers which do not have users on the channel will receive the message or act upon it.


Server Types

InspIRCd has three types of server. Although the same in design, and speaking the same protocol, their behaviours are different due to the roles they play in maintaining the network. These are:


A hub is categorized as any server which has more than one locally connected server. A hub differs from normal operation in that the bandwidth passing through a hub is usually much greater than that passing through a leaf, and it may expend more computing power to run a hub.


A leaf is categorized as any server which has only one, or no connected servers. A leaf does not have to route as much information as a hub (see above) but usually because of this is configured to hold many more clients as it has the spare computer power to hold the users.


A U lined server is usually a leaf server, however in InspIRCd, a hub may also be U lined. U lined servers have many extra privilages, which are required for example to operate a services server or similar. U lines must be individually configured on all servers to work, and all servers must be in agreement about the names of the U lined servers. If they are not in agreement, mode changes will be dropped and commands forbidden which should operate normally.

Timestamp Syncronization

Because the InspIRCd spanning tree protocol operates using timestamps based around the UNIX "epoch" value, you must ensure that all clocks are synchronized on your network. This is best done with ntpd or ntpdate. If you do not synchronize the clocks on your servers, you will find that timestamp calculations will exhibit strange results, and users will be randomly deopped in new channels.

The InspIRCd spanning tree protocol should build in a margain of error of up to ten minutes (600 seconds) for FJOINs to new channels only, so that upon the clocks being out of sync, new channels can still be created successfully.

Example Traffic

This is an example of a netburst and some random traffic between InspIRCd 1.1.0 and IRCServices, running the newer IRCServices module, which is shown here to aid those wanting to see first hand how InspIRCd behaves when sent certain commands, etc.

This example shows a connection to a test network with two connectable servers and a services server:

[09:31] ---
[09:31] --- `
[09:31] ---   `
[09:31] --- End of /MAP
Initiated connection to
Received: CAPAB MODULES,,,,,,
Received: CAPAB MODULES,,,,
Received: CAPAB MODULES,,,,,,,,
Received: CAPAB MODULES,,,,,,
Received: CAPAB END
Sent: SERVER password 0 :IRCServices test server
Sent: BURST 1133994664
Sent: VERSION :ircservices-5.0.56 :build #26, compiled Wed Dec  7 11:31:19 GMT 2005
Sent: NICK 1133994664 OperServ services +oi :Operator Server
Sent: NICK 1133994664 Global services +oi :Global Noticer
Sent: NICK 1133994664 NickServ services +oi :Nickname Server
Sent: NICK 1133994664 ChanServ services +oi :Channel Server
Sent: NICK 1133994664 MemoServ services +oi :Memo Server
Sent: NICK 1133994664 StatServ services +i :Statistics Server
Sent: NICK 1133994664 HelpServ services +i :Help Server
Sent: NICK 1133994664 DevNull services +i :/dev/null -- message sink
Sent: ADDLINE G [email protected] Brain 1133994664 0 :You are banned from this network
Received: SERVER password 0 :ChatSpike InspIRCd test server
Received: BURST 1133994664
Received: VERSION :InspIRCd-1.1.0+SVN(r5000) :FreeBSD 5.4-RELEASE [FLAGS=0,kqueue,singlethread-object]
Received: SERVER * 1 :Second server
Received: VERSION :InspIRCd-1.1.0+SVN(r5000) :Linux brainwave 2.6.12-gentoo-r6 [FLAGS=0,epoll,singlethread-object]
Received: NICK 1133992412 Brain ~brain +xwsioS :Craig Edwards
Sent: :NickServ SVSMODE Brain :-r
Sent: :NickServ NOTICE Brain :This nickname is registered and protected.  If it is your nickname, type /msg NickServ IDENTIFY password.  Otherwise, please choose a different nickname.
Sent: :OperServ GLOBOPS :Brain is now an IRC operator.
Received: :Brain OPERTYPE NetAdmin
Received: METADATA Brain swhois :blah blah test blah
Received: NICK 1133992705 Brain2 0284D4C2C220AFC6.Blah.cloak ~brain +xwsi :Craig Edwards
Received: NICK 1133992510 w00teh ~w00t +x :Robin Burchell
Received: NICK 1133992412 DesktopOm ~om +xwsioS :><(((\uffff\uffff>
Sent: :NickServ SVSMODE DesktopOm :-r
Sent: :NickServ NOTICE DesktopOm :This nickname is registered and protected.  If it is your nickname, type /msg NickServ IDENTIFY password.  Otherwise, please choose a different nickname.
Sent: :OperServ GLOBOPS :DesktopOm is now an IRC operator.
Received: :DesktopOm OPERTYPE NetAdmin
Received: NICK 1133992598 Ghost ~Ghost +x :Ghost
Received: NICK 1133992430 Cyan 67B46DBE20695D01.InspIRCd-Testnet.cloak ~cyan +xiw :Cyan Garamonde
Received: NICK 1133992409 Omster ~om +xwsi :Mr. Tiddles
Received: FJOIN #test 1133992411 :,Omster ,Brain ,DesktopOm ,Cyan ,w00teh ,Ghost ,Brain2
Sent: FTOPIC #test 1133865017 Ghost :This is a test server. Support network at -- Yes, this ircd package will eventually replace unreal on ChatSpike | Pwnd by Ghost
Received: FMODE #test 1133994664 +ntr
Received: FTOPIC #test 1133865017 Ghost :This is a test server. Support network at -- Yes, this ircd package will eventually replace unreal on ChatSpike | Pwnd by Ghost
Received: ADDLINE Z <Config> 1133992407 0 :This is the devils ip. You cannot use it.
Received: ADDLINE Z <Config> 1133992705 0 :No porn here thanks.
Received: ADDLINE Q *[rxHO]* <Config> 1133992407 0 :Script kiddiot.
Received: ADDLINE Q ChanServ <Config> 1133992705 0 :Reserved For Services
Received: ADDLINE Q NickServ <Config> 1133992705 0 :Reserved For Services
Received: ADDLINE Q OperServ <Config> 1133992705 0 :Reserved For Services
Received: ADDLINE Q MemoServ <Config> 1133992705 0 :Reserved For Services
Received: ADDLINE G [email protected] Brain 1133992727 0 :You are banned from this network
Received: ADDLINE E * <Config> 1133992705 0 :Opers hostname
Received: ENDBURST
Sent: :ChanServ MODE #test +ntr
Received: :Brain PRIVMSG NickServ : identify xxxxxxx
Sent: :NickServ NOTICE Brain :Password incorrect.
Received: PING
Sent: PONG