diff --git a/INSTALL b/INSTALL index 41b6e815..3278314d 100644 --- a/INSTALL +++ b/INSTALL @@ -7,8 +7,8 @@ ircu - INSTALL Compiling and installing ircu should be a fairly straightforward process, if you have obtained this software as a (.tar.gz) package, please consider -using CVS (described below). Using CVS will make updating your installation -much easier. +using git (described below). Using git will make updating your installation +much easier. After obtaining the latest version of the ircu source code, change into the source directory (ircu2.10.xx.yy), and run "./configure". To see the various @@ -40,22 +40,14 @@ compiled during "make" and installed to $PREFIX/bin/convert-conf. Good Luck! -RETRIEVING IRCU VIA CVS +RETRIEVING IRCU VIA GIT -The recommended way to get the ircu package now is to use CVS. CVS makes -upgrades a lot less painful and lets you get the latest package. +The recommended way to get the ircu package is to clone the git +repository: +# git clone https://github.com/UndernetIRC/ircu2.git -The first thing you need to do is login to the cvs server: -# cvs -d :pserver:anonymous@cvs.undernet.org:/cvsroot/undernet-ircu login - -(we recommend that you cut and paste the above line to use it :) -When it prompts you for a password hit enter since there isn't one. - -To check out the the last development version of ircu, use: -# cvs -d :pserver:anonymous@cvs.undernet.org:/cvsroot/undernet-ircu co -P ircu2.10 -The latest stable version has a tag name that depends on the version -number; see doc/readme.cvs for details. - -To update your source tree to the latest version, run "cvs update -dP" from within the -ircu2.10 directory. For more information, see http://coder-com.undernet.org. +The default branch (main) is used for development; the current +release series lives on u2_10_12_branch and releases are tagged. +To update your source tree to the latest version, run "git pull" +from within the ircu2 directory. diff --git a/RELEASE.NOTES b/RELEASE.NOTES index 47106bd1..3553e7f0 100644 --- a/RELEASE.NOTES +++ b/RELEASE.NOTES @@ -37,7 +37,7 @@ from ircd-hybrid) that avoids some of the complications from using the full libresolv or adns libraries. The server can query an IAUTH external authorization server. The -protocol is described in doc/readme.iauth. This allows an external +protocol is described in doc/readme.iauth.md. This allows an external program to accept or reject any client that connects to the server and allows that external program to assign an account stamp to the incoming user. diff --git a/configure.ac b/configure.ac index 89d4cc48..6e2cef32 100644 --- a/configure.ac +++ b/configure.ac @@ -547,13 +547,13 @@ AC_MSG_CHECKING([if chroot operation is desired]) AC_ARG_WITH([chroot], [ --with-chroot=dir Specify that the server will be operated under a different root directory given by dir. See - doc/readme.chroot for more information.], + doc/history/readme.chroot for more information.], [unet_cv_with_chroot=$with_chroot], [AC_CACHE_VAL(unet_cv_with_chroot, [unet_cv_with_chroot=no])]) if test x"$unet_cv_with_chroot" = xyes; then - AC_MSG_ERROR([--with-chroot given with no directory. See doc/readme.chroot.]) + AC_MSG_ERROR([--with-chroot given with no directory. See doc/history/readme.chroot.]) fi # Ensure there are no trailing /'s to mess us up diff --git a/doc/.cvsignore b/doc/.cvsignore deleted file mode 100644 index 190b6d1e..00000000 --- a/doc/.cvsignore +++ /dev/null @@ -1,3 +0,0 @@ -Makefile -stamp-m -doxygen diff --git a/doc/example.conf b/doc/example.conf index 2f857dbf..cfeaebe7 100644 --- a/doc/example.conf +++ b/doc/example.conf @@ -628,7 +628,7 @@ Kill # then TLS fingerprint and ciphers are used. If "tls fingerprint" is # present, the other server must use a certificate with that fingerprint. # If "tls ciphers" is present, it is given to the TLS library to restrict -# or prioritize particular algorithms. (See TLS_CIPHERS in readme.features +# or prioritize particular algorithms. (See TLS_CIPHERS in readme.features.md # for details.) # # TLS trust for outbound server links is configured per Connect block. @@ -704,7 +704,7 @@ Connect { # [crule] # # For an advanced, real-time rule-based routing decision making system -# you can use crule blocks. For more information, see doc/readme.crules. +# you can use crule blocks. For more information, see doc/readme.crules.md. # If more than one server mask is present in a single crule, the rule # applies to all servers. # CRULE @@ -839,7 +839,7 @@ Operator { # # want WebIRC ports to also be hidden. # WebIRC = yes; # # Setting tls ciphers affects which TLS cipher suites are allowed on -# # this port. See TLS_CIPHERS in readme.features for more details. +# # this port. See TLS_CIPHERS in readme.features.md for more details. # tls ciphers = ""; # tls cacertfile = "/etc/ircd/network-ca.pem"; # tls cacertdir = "/etc/ircd/trust/"; @@ -1079,15 +1079,15 @@ IPCheck { # are listed below, and at the bottom is how to set logging. # # A Special Thanks to Kev for writing the documentation of F:lines. It can -# be found at doc/readme.features and the logging documentation can be -# found at doc/readme.log. The defaults used by the Undernet network are +# be found at doc/readme.features.md and the logging documentation can be +# found at doc/readme.log.md. The defaults used by the Undernet network are # below. # features { # These log features are the only way to get certain error messages # (such as when the server dies from being out of memory). For more -# explanation of how they work, see doc/readme.log. +# explanation of how they work, see doc/readme.log.md. "LOG" = "SYSTEM" "FILE" "ircd.log"; "LOG" = "SYSTEM" "LEVEL" "CRIT"; # "DOMAINNAME"=""; diff --git a/doc/features.txt b/doc/features.txt index 74fbb0df..d3154a6e 100644 --- a/doc/features.txt +++ b/doc/features.txt @@ -8,7 +8,7 @@ numeric replies should be added here too. Extended Who information: (WHOX) Version: unknown, but at least 2.10.07+ - This is described in the file 'readme.who' + This is described in the file 'readme.who.md' USERIP: Version: unknown, but at least 2.10.07+ @@ -140,7 +140,7 @@ User modes: undernet service bots (X/W/UWorld etc) +g: List channel HACK:'s +s: Server messages - takes a parameter of which masks to send, see - 'snomask.html' for more details. (2.10.0+) + 'snomask.md' for more details. (2.10.0+) +R: Block unauthenticated users. PRIVMSG, NOTICE and INVITE from users that are not authenticated to a registered account are blocked. PRIVMSG and INVITE are rejected with ERR_NEEDREGGEDNICK (477); diff --git a/ChangeLog.11 b/doc/history/ChangeLog.11 similarity index 100% rename from ChangeLog.11 rename to doc/history/ChangeLog.11 diff --git a/ChangeLog.12 b/doc/history/ChangeLog.12 similarity index 100% rename from ChangeLog.12 rename to doc/history/ChangeLog.12 diff --git a/doc/debug_memleak_gc.patch b/doc/history/debug_memleak_gc.patch similarity index 100% rename from doc/debug_memleak_gc.patch rename to doc/history/debug_memleak_gc.patch diff --git a/doc/linux-poll.patch b/doc/history/linux-poll.patch similarity index 100% rename from doc/linux-poll.patch rename to doc/history/linux-poll.patch diff --git a/doc/readme.chroot b/doc/history/readme.chroot similarity index 100% rename from doc/readme.chroot rename to doc/history/readme.chroot diff --git a/doc/readme.www b/doc/history/readme.www similarity index 100% rename from doc/readme.www rename to doc/history/readme.www diff --git a/doc/p10.html b/doc/p10.html deleted file mode 100644 index fbbc4fe8..00000000 --- a/doc/p10.html +++ /dev/null @@ -1,1184 +0,0 @@ - - - - - - Undernet P10 Protocol and Interface Specification - - - -

-Undernet P10 Protocol and Interface Specification

-(As of ircu 2.10.11) -

-Undernet Coder-com, coder-com@undernet.org

-$Id: p10.html,v 1.6 2002-02-14 00:20:40 ghostwolf Exp $ -

-


This document aims to be a practical -guide for implementing and maintaining the protocol, not just a reference -manual. -

This document is "work in progress" and being continually updated :) -


-
1. Introduction -

2. General concepts and background -

2.1 Concepts. -
2.2 Token Table.
- -

-3. Registration and syncronisation

- - - -

-4. Continous operation

- - - -

-4. Programmers reference: Function headers

- - - -

-5. Programmers reference: Client/Server Structures

- -

-6. FAQ

- -

-7. Acknowledgements and disclaimer

- -

-8. Update History

- -
-
  • -TODO List
  • -
    - -
    -
    - -

    1. Introduction -

    [Back] -
    -


    -

    2. General concepts and background -

    2.1 Concepts -

    The undernet P10 protocol uses a scheme of "Numerics" to uniquenly 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). -

    The numerics are encoded into a Base64 stream to maintain human readable -data flow and reduce the size of the messages. The Base64 character set -used in ircu is included below, this defines all valid characters allowed -in a Base64 numeric with "A" representing 0 and "]" representing 63. -

    -
    ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789[]
    -
    -Server numerics consist of 2 characters, with the minimum, 0, being represented -by "AA", and the maximum, 4095, being represented by "]]". Client numerics -are 3 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.undernet.org" which has a numeric -of 2, translating to "AC" in Base64. On this server exists a client, whom -has been allocated the numeric 63 (which translates to "AA]" in Base64). -Therefore, the unique identifier of this client on the network is "ACAA]". -From this, we can determine which server the message came from, aswell -as the client who sent it. -

    These numerics are used to prefix every message issued on the stream -except for the initial "PASS" or "SERVER" message, which are not prefixed. -Therefore, every message that can be recieved from a server will consist -of the format: -

    -
    [NUMERIC PREFIX] [TOKEN] [DATA]
    -
    -For Example: -
    -
    A[A5j P ABAAA :Foo.
    -
    -2.2 Token Table -

    The following table lists all the acceptable messages, along with their -relevant "Token", which is used in the server<>server protocol. The -aim of tokenisation is to reduce the bandwidth used during network communication -by reducing the length of common message identifiers. -
      -

    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    MessageToken
    PRIVMSGP
    WHOH
    WHOISW
    WHOWASX
    USERUSER
    NICKN
    SERVERS
    LISTLIST
    TOPICT
    INVITEI
    VERSIONV
    QUITQ
    SQUITSQ
    KILLD
    INFOF
    LINKSLI
    STATSR
    HELPHELP
    ERRORY
    AWAYA
    CONNECTCO
    MAPMAP
    PINGG
    PONGZ
    OPEROPER
    PASSPA
    WALLOPSWA
    DESYNCHDS
    TIMETI
    SETTIMESE
    RPINGRI
    RPONGRO
    NAMESE
    ADMINAD
    TRACETR
    NOTICEO
    WALLCHOPSWC
    CPRIVMSGCP
    CNOTICECN
    JOINJ
    PARTL
    LUSERSLU
    MOTDMO
    MODEM
    KICKK
    USERHOSTUSERHOST
    USERIPUSERIP
    ISONISON
    SQUERYSQUERY
    SERVLISTSERVLIST
    SERVSETSERVSET
    REHASHREHASH
    RESTARTRESTART
    CLOSECLOSE
    DIEDIE
    HASHHASH
    DNSDNS
    SILENCEU
    GLINEGL
    BURSTB
    CREATEC
    DESTRUCTDE
    END_OF_BURSTEB
    END_OF_BURST_ACKEA
    PROTOPROTO
    JUPEJU
    OPMODEOM
    CLEARMODECM
    ACCOUNTAC
    -[Back] -
    -
    -

    3. Registration and syncronisation -

    3.1 Server registration and authentication -

    After a TCP connection has been established, the server initally introduces -itself via a "PASS" message as follows: -

    -
    PASS :[PASSWORD]
    -
    -"PASSWORD" is simply compared with the password present in the destination -servers config file, and is used to confirm credentials after the "SERVER" -message has been recieved, as follows: -
    -
    SERVER [SERVERNAME] [HOPCOUNT] [START TIME] [LINK TIME] [PROTOCOL] [NUMERIC/MAXCONN] :[DESCRIPTION]
    -
    -For Example: -
    -
    1      2                3 4         5         6   7     8 
    -SERVER irc.undernet.org 1 933022556 947908144 J10 AA]]] :[127.0.0.1] A Undernet Server.
    -
    -Notes: -
      -
    1. -The SERVER message, indicating this connection wishes to introduce a new -server to the network.
    2. - -
    3. - The name of the server you are introducing, a valid server name consists -of [..defn..].
    4. - -
    5. - The hop count of the server you are introducing, this is always 1 -when you are introducing yourself.
    6. - -
    7. - The epoch timestamp specifying when the ircd was started.
    8. - -
    9. - The epoch timestamp specifying the time the server initiated the -link to the network.
    10. - -
    11. - The Protocol identifier of this server.
    12. - -
        -
      1. -This token informs the network which protocol it is compliant with, eg: -If it is a P10 compliant server, then the token will be "P10".
      2. - -
      3. - If the server being introduced has not yet successfully synced its -database with the network (Completed its net.burst - see 3.2), then the -Protocol token should be prefixed with a J, instead of a P (Eg: J10) to -indicate it is currently still joining the network.
      4. - -
      5. - The protocol token should always be JXX when the server is introducing -itself.
      6. -
      - -
    13. -The numeric, and maximum connections identifier for this server.
    14. - -
        -
      1. -This token is formatted exactly the same as a client numeric is formatted. -The first 2 characters identify the server's numeric, whilst in this situation, -the final 3 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, because the server -uses this as a bitmask. A server can give out a higher numeric than this, -however it will be "anded" with this number to find it's entry slot. The -reason for this is so a server which is near the maximum number of clients -can give out more numerics than it's using to prevent a new client getting a -numeric that was used only seconds ago and maybe get messages destined to -the old user.
      2. - -
      3. - The example "AA]]]" shows that this is a server with numeric 0, which -will generate client numerics up to 262,143.
      4. -
      - -
    15. -This final parameter simply consists of a textual description of the server -prefixed by a colon. This is displayed in a clients WHOIS line, aswell -as in the LINKS reply. By convention, if this is a leaf server it contains -the servers IP in square brackets at the beginning of the string,
    16. -
    -3.2 Network Database resyncronisation -

    After the connection has been established and verified, the next step -is to syncronise the database of client/server/channel information between -the two servers. -

    3.2.1 - SERVER Messages
    - -
    Server details are transmitted via "SERVER" messages similar -to the initial introduction message, with the following format:
    - -
    -
    [OWNING SERVER PREFIX] S [SERVERNAME] -[HOPCOUNT] [START TIME] [LINK TIME] [PROTOCOL] [NUMERIC/MAXCONN] 0 :[DESCRIPTION]
    -The syntax of this message is almost identical to -the originally recieved server message, with the only exception being that -the message is numeric prefixed, to indicate which server sent this message -(and also therefore, which hub this new server is linked too). There is -also a fixed "0" present before the Description field, this is a placeholder -for future use and currently unused. [Isomer: Question, what IS this -reserved for?] -

    3.2.2 - NICK Messages

    - -
    Client information is transmitted via "NICK" messages, of the -following format:
    - -
    -
    -
    [NUMERIC PREFIX] N [NICK] [HOPCOUNT] [TIMESTAMP] [USERNAME] [HOST] <+modes> [BASE64 IP] [NUMERIC] :[USERINFO]
    -
    -For Example: -
    1  2 3       -4 5         6     -7            8     -9      10    11 -
    AF N Client1 1 947957573 User userhost.net -+oiwg DAqAoB AFAAA :Generic Client.
    -Notes: -
      -
    1. -The numeric of the server sending this message. (And hence, owning this -client).
    2. - -
    3. -The "NICK" token.
    4. - -
    5. -The nickname of this client, currently max 9 chars.
    6. - -
    7. -The "Hopcount" of this client, Ie: how many servers away it is on.
    8. - -
    9. -The epoch timestamp indicating when the user was created.
    10. - -
    11. -The "User" part of the user@host mask.
    12. - -
    13. -the "Host" part of the user@host mask.
    14. - -
    15. -[Optional]: User modes. If present, this is always +<user modes -for this client>. Note that the special +r usermode is followed by the -client's account name; see the documentation for ACCOUNT.
    16. - -
    17. -The real IP address of this client, a Base64 encoded 32bit int.
    18. - -
    19. -This client's numeric, in SSCCC format.
    20. - -
    21. -Free format user info line.
    22. - -
       
    -
    - -
    3.2.3 - BURST Messages
    - -
    Channel details and membership information is synchronised -in one (or more) BURST messages for each channel that exists, formatted -as follows:
    - -
    -
    -
    [NUMERIC PREFIX] B [CHANNEL] [CREATION TIMESTAMP] <+MODES> <ARG1> <ARG2> [MEMBER LIST] <:%BANS>
    -
    -
    - -
    For Example:
    - -
    -
    -
    1  2 3          4         5      6   7  8                                         9
    -AZ B #coder-com 949217470 +tinkl key 56 AAAAA,AAAAB,AAAAC,ABAAA,ABAAB,ABAAC,ACAAA :%*!*@*.net
    -
    -
    - -
    Notes:
    - -
      -
    1. -The numeric of the server sending this message.
    2. - -
    3. -The "BURST" token.
    4. - -
    5. -The name of the channel to which this data belongs. Currently #Channel -and +Channel names can be sent in a BURST message, &Channels are not -because by definition they are local to the server.
    6. - -
    7. -The epoch timestamp indicating when the channel was created.
    8. - -
    9. -[Optional]: Channel Modes.
    10. - -
        -
      1. -The channel may have a number of modes set, aswell as relevant mode arguments -in the following 2 parameters.
      2. -
      - -
    11. -[Optional]: Channel Key, this parameter is present if the channel -modes contain a "k" mode.
    12. - -
    13. -[Optional]: Channel Limit, this parameter is present if the channel -modes contain a "l" mode.
    14. - -
    15. - A comma seperated list of client numerics, with the following -specific formatting rules to indicate +o, +v and +ov channel members.
    16. - -
        -
      1. -Numerics can have the following symbols appended on them; ":ov", -":v" or ":o". These indicate that this numeric is either -Opped (:o), Voiced (:v) or both (:ov). This state -applies to the numeric it is attached too, and all subsequent numerics -until another state is encountered. For Example:
      2. - -
      3. -AAABA:ov, AAABB:o,AAABC,AAABD,AAABE:v,AAABZ
      4. - -
        Here, AAABA is both opped, and voiced, AAABB, AAABC and AAABD are opped -leaving AAABE and AAABZ voiced. -
      5. - The first numeric of the member list will always contain a state -symbol.
      6. -
      - -
    17. -A space seperated list of bans present in the channel. The start -of the ban stream is indicated by a ":%", everything following the ":%" -is the ban list.
    18. - -
      For Example: -
      :%*!*@*.foobar.net another!ban@*.com *!*fred@a.host.co.uk -
      Would add the following bans to the channel: -

      *!*@*.foobar.net -
      another!ban@*.com -
      *!*fred@a.host.co.uk

    - -
    If the length of a BURST message exceeds the maximum lenght -of a line (512 characters) then the remaining channel members/bans are -sent in subsequent BURST lines. The subsequent burst lines are only -used to add additional members to the channel, and if neccessary, channel -bans. There will be no "Mode" parameters present. A sample additional burst -line would be:
    - -
    -
    -
    AZ BURST #coder-com 949217470 ACAAB:o,ACAAD :%*!*another@*.ban.com
    -
    -
    - -
    Which adds two more opped members and a ban to the channel.
    - -
    3.2.4 - JUPE Messages
    - -
    Any currently unexpired JUPEs are transmitted via "JUPE" messages -with the following format:
    - -
    -
    [NUMERIC PREFIX] JU * (+|-)[SERVER -NAME] [LIFETIME] [LAST MOD] :[REASON]
    -For example:
    - -
    -
    1  2  3 4                -5         6         -7 -
    AZ JU * +juped.undernet.org 000003593 955419707 -:Juped Server
    -Notes:
    - -
      -
    1. -The numeric of the server sending this message.
    2. - -
    3. -The "JUPE" token.
    4. - -
    5. -The target that should apply this JUPE (always "*" during bursts).
    6. - -
    7. -The name of the server to JUPE, prefixed with a "+" if the JUPE is active, -or with a "-" if it is not.
    8. - -
    9. -The remaining absolute lifetime of the JUPE, expressed in seconds.
    10. - -
    11. -The last time the JUPE was modified.
    12. - -
    13. -The reason the JUPE was applied.
    14. -
    -3.3 Summary -

    The following table summarises the sequence of events that occur when -a server connects to another server. S1 is our server, and S2 is a HUB -on the target network. -

    S1: Sends Password. -
    S1: Sends initial SERVER message. -

    S2 Confirms S1 has the correct credentials, and if so, proceeds. -If not, S1 is squit with a relevant reason. -

    S2: Sends Password. -
    S2: Sends initial SERVER message. -

    S1 Confirms S2 has the correct credentials, and if so, proceeds. -If not, S2 is squit with a relevant reason. -

    The follow occur asynchronously, however they have been shown -seperately below for simplicity. -

    S1: Sends all the servers it is aware of as a stream of SERVER messages. -
    S1: Sends all the clients it is aware of as a stream of NICK messages. -
    S1: Sends the database of channel states on the network, as a stream -of BURST messages. -
    S1: Sends all the jupes it is aware of as a stream of JUPE messages. -
    S1: Sends a END_OF_BURST token (EB) to indicate it has finished sending. -

    S2: Sends all the servers it is aware of as a stream of SERVER messages. -
    S2: Sends all the clients it is aware of as a stream of NICK messages. -
    S2: Sends the database of channel states on the network, as a stream -of BURST messages. -
    S2: Sends all the jupes it is aware of as a stream of JUPE messages. -
    S2: Sends a END_OF_BURST token (EB) to indicate it has finished sending. -

    S2: Sends an EOB_ACK token (EA) to indicate it has succesfully recieved -the END_OF_BURST from S1 -
    S1: Sends an EOB_ACK token (EA) to indicate it has succesfully recieved -the END_OF_BURST from S2 -

    Example Session: -

    [WRITE]: PASS :54321
    -[WRITE]: SERVER irc.undernet.org 1 947957852 947957852 J10 AB]]] :Undernet Client Server.
    -[WRITE]: AB N MrFoo 1 947957852 ~me myhost.foobar.net +diksw DAqAoB ABAAA :Mr Foo (foo@bar.com).
    -[WRITE]: AB B #mychannel 946101324 ABAAA:o
    -[WRITE]: AB EB
    -[ READ]: PASS :54321
    -[ READ]: SERVER server1.undernet.org 1 947901540 947958150 J10 AFAD] :A Generic Server.
    -[ READ]: AF S server2.undernet.org 2 0 947957585 P10 AZAD] 0 :[192.168.10.3] A Generic Server.
    -[ READ]: AZ S server3.undernet.org 3 0 947957607 P10 AIAD] 0 :[192.168.10.5] A Generic Server.
    -[ READ]: AF N Client1 1 947957573 Ident userhost.net +oiwg DAqAoB AFAAA :Generic Client.
    -[ READ]: AZ N Client2 2 947957719 Ident userhost.net +iwg DAqAoB AZAAA :Generic Client.
    -[ READ]: AI N Client3 3 947957742 Ident userhost.net +iwg DAqAoB AIAAA :Generic Client.
    -[ READ]: AI N Client4 3 947958121 Ident userhost.net +iwg DAqAoB AIAAB :Generic Client.
    -[ READ]: AF B #foobar 947957734 +tink akey AIAAB,AIAAA:v,AZAAA:o :%*!*another@*.ban.com *!*foo@bar.net
    -[ READ]: AF B #coder-com 947957727 AIAAB,AZAAA:o
    -[ READ]: AF B #another 946101321 AFAAA
    -[ READ]: AF JU * +juped.undernet.org 3600 947958100 :Broken, please fix
    -[ READ]: AF EB
    -[WRITE]: AB EA
    -[ READ]: AF EA
    -[Back] -
    -
    -
    4. Continuous Operation -

    This chapter provides details of the messages that can be sent after -successfully linking to a network, and synchronising the channel/user database. -

    4.1 Channel state operations -

    There are a number of messages that can modify the state of a channel, -these are: -

      4.1.1 - MODE -

      The MODE message can modify channel modes and bans, and also give or -take operator/voice status from channel members. -

          -
        [NUMERIC PREFIX] M [CHANNEL] (+|-)[MODESTRING] -<MODESTRING PARAMETERS>
      - -


      For Example: -

          -
        1     2 3          -4        5 -
        AZAAA M #coder-com +stinlko 500 TestKey BAC
      - -


      Notes: -
        -

        -
      1. -The numeric of the user issuing this MODE command. It can be assumed this -user is opped on the target channel.
      2. - -
      3. -The "MODE" token.
      4. - -
      5. -The target channel.
      6. - -
      7. -The "Mode string".
      8. - -
          -
        1. -This consists of up to 6 '+' or '-' (add or remove) prefixed channel modes. -(If no '+' or '-' are specified, a '+' is assumed unless a '-' has been -encountered previously in the mode string). For example, '+s+t+n-l-io' -is a valid mode string, as is '+stnmov'.
        2. - -
            -
        3. -Valid Mode modes are:
        4. -
        -
      - -
        -
            - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
          TokenFunctionParameters
          pSets/Unsets 'Private' Flag.None.
          sSets/Unsets 'Secret' Flag.None.
          mSets/Unsets 'Moderated' Flag.None.
          nSets/Unsets 'External Messages' Flag.None.
          tSets/Unsets 'Topic Limit' Flag.None.
          iSets/Unsets 'Invite only' Flag.None.
          lSets/Unsets 'Channel Limit' Flag.The channel limit.
          kSets/Unsets 'Channel Key' Flag.The channel keyword (Password).
          oOps and Deops users.Numeric of user to be opped.
          vVoiceNumeric of user to be voiced.
          bBanBan string.
          -
        -
      - -
        -
      1. -The "Mode string Parameters".
      2. - -
          -
        1. -This is a matching list of parameters to the modes supplied in the "Modestring".
        2. - -
          For Example: -
          If the Modestring is "+stnlo", a typical parameter string would be -"500 AZAA". The first 3 modes, 's', 't' and 'n' do not require parameters, -so non are present. The following two, 'l' and 'o' both require parameters, -so they are 500 and AZAAA respectively (This sets the channel limit to -500 users, and ops the numeric AZAAA).
        -
      - -


      N.B: The "MODE" message is also used to modify a client's user modes, -not just channel modes. See section 4.2 for details.

    - -
      4.1.2 - OPMODE -

      The OPMODE message is identical in syntax to the MODE message, however -it will only ever have an operator as the source. It is likely that the -source of this mode will not have ops in the target channel, but it should -succeed never the less. -

      4.1.3 - JOIN -

      4.1.4 - PART -

      4.1.5 - KICK -

      4.1.6 - TOPIC -

      4.1.7 - CLEARMODE -
        -

        AZAAA CM #coder-com ovpsmikbl
      -
    -4.2 Client state operations -
    4.2.1 - NICK -
    AZAAA N Nick2 955423230
    -4.2.2 - MODE -
    AZAAA M Nick2 :+odi
    -4.2.3 - ACCOUNT -
    AX AC AZAAA oper
    -

    The ACCOUNT message provides a way for servers, such as the channel service -server, to set the account name information that is associated with a client. -Once set, it cannot be unset or changed, and will be propagated in NICK during -net bursts using the special user mode +r followed by the account name. -

    -4.3 Channel/Client Messaging. -
    4.3.1 - PRIVMSG -

    4.3.2 - NOTICE -

    4.3.3 - CNOTICE -

    4.3.4 - CPRIVMSG -
     

    -[Back] -
    -
    -

    5. Programmers reference: Client/Server -Structures -

    This section provides information on the standard Client/Server structures, -for easy reference during development. -

    [..Link to autogenerated struct.html..] -

    [Back] -
    -


    -
    7. FAQ -

    Frequently asked questions. -

    -[Back] -
    -
    -

    8. Update History -

    [2000-01-20]: Initial draft, structure, background info. -
    [2000-02-13]: Added initial BURST documentation. -
    [2000-02-14]: Continued BURST documentation / Begin NICK and SERVER -documentation. -
    [2000-02-26]: Continued chapter 5, few example fixes, added token table -from msg.h. -Gte. -
    [2000-03-02]: Added NICK spec. -Gte. -
    [2000-03-18]: Added JUPE spec. -Kev -
    [2000-04-10]: Added information about OPMODE and CLEARMODE tokens. --Kev -
    [2000-04-11]: Started work on chapter 4. -Gte -
    [2000-06-01]: Changed some info about the max number of clients -Isomer -
    [2002-01-11]: Wrote a specification for ACCOUNT and noted that a usermode -in a NICK message may have an argument. -Kev -

    8.1 TODO -

    -[Back] - - diff --git a/doc/p10.md b/doc/p10.md new file mode 100644 index 00000000..46f83207 --- /dev/null +++ b/doc/p10.md @@ -0,0 +1,1759 @@ +# P10 Server-to-Server Protocol + +This document describes the P10 protocol as implemented by this ircu2 tree +(base version u2.10.13, protocol major version 10, plus the extensions +carried in this repository). It covers the server-to-server (S2S) side only: +what one server sends to another, what it expects back, and how each message +is validated, applied and propagated. Client-to-server behaviour is mentioned +only where it is needed to explain an S2S message. + +--- + +## Table of contents + +1. [Wire format](#1-wire-format) +2. [Numerics and encodings](#2-numerics-and-encodings) +3. [Token table](#3-token-table) +4. [Link establishment](#4-link-establishment) +5. [The net burst](#5-the-net-burst) +6. [Server and link management](#6-server-and-link-management) +7. [Users](#7-users) +8. [Channels](#8-channels) +9. [Messaging](#9-messaging) +10. [Network-wide policy: G-lines, Jupes, S-lines, CONFIG](#10-network-wide-policy) +11. [Extension queries (services RPC)](#11-extension-queries) +12. [Remote queries and numeric relaying](#12-remote-queries-and-numeric-relaying) +13. [IRCv3 message tags on server links](#13-ircv3-message-tags-on-server-links) +14. [Timestamps and conflict resolution](#14-timestamps-and-conflict-resolution) +15. [Reference tables](#15-reference-tables) +16. [Example session](#16-example-session) +17. [Compatibility notes](#17-compatibility-notes) + +--- + +## 1. Wire format + +### 1.1 Lines + +A P10 link is a stream of lines terminated by `\r\n` (a lone `\n` is +accepted). The IRC body of a line is at most 512 bytes including the +terminator (`BUFSIZE`). An optional IRCv3 tag block may precede the body and +does not count towards the 512 bytes; the tag block itself is limited to +`TAGSLEN` (8191) bytes and a server may send up to `TAGDATA_SERVER_MAX` +(4094) bytes of tag data on one line. See section 13. + +A line has the general form: + +``` +[@tag1=val;tag2 ] [ ...] [:] +``` + +Parameters are separated by one or more spaces. A parameter beginning with +`:` swallows the rest of the line (spaces included). At most `MAXPARA` (15) +parameters are split; anything after the fifteenth is left in the last one. + +### 1.2 Prefix + +Every line sent on an established server link carries a prefix identifying +the originator. The only exceptions are the `PASS` and `SERVER` lines a +server sends to introduce itself, and the `ERROR` line sent when closing a +link that never registered. + +Two prefix forms are accepted by `parse_server()`: + +| Form | Meaning | +|------|---------| +| `AB` or `ABAAC` (no leading colon) | Numeric of a server (2 chars) or user (5 chars). This is the normal P10 form. One-character server numerics and three-character user numerics are also decoded for legacy (P09) peers. | +| `:name` (leading colon) | A server or nick name. Accepted for backwards compatibility; not generated by this implementation on server links. | + +The parser distinguishes the two numeric lengths by looking at where the +first space falls: a space at offset 1 or 2 means a server numeric, +otherwise a user numeric. + +A message whose prefix cannot be resolved is normally dropped as a lagged +message that raced an SQUIT. Three exceptions travel "upstream" against an +SQUIT and are re-attributed to the sending link: `SQUIT` (`SQ`), `KILL` +(`D`) and a `KILL` written out longhand. If an unknown user numeric is seen +as the source of a `NICK` (nick change), the receiving server sends a +`KILL` for that numeric back to the link it came from so the ghost is +cleaned up. + +A message whose prefix resolves to a client that is not reachable through +the link it arrived on is a "fake direction" message and is dropped +silently. + +### 1.3 Commands and tokens + +On a server link each command is sent as its short token (`P` for +`PRIVMSG`, `N` for `NICK`, ...). The receiver accepts both the token and +the long name. The complete table is in section 3. + +A command consisting of exactly three digits is a numeric reply being +relayed to a remote client; see section 12. + +### 1.4 Formatting conventions used below + +Within this document: + +- `` is a two-character server numeric, `` a five-character + user numeric, `` either of the two. +- `` is a UNIX timestamp in decimal. +- Optional fields are in `[brackets]`; `...` means repetition. +- Examples show the literal wire form, without the trailing `\r\n`. + +--- + +## 2. Numerics and encodings + +### 2.1 Base64 alphabet + +All numeric identifiers use a fixed 64-character alphabet with `A` = 0 and +`]` = 63: + +``` +ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789[] +``` + +The following characters can never appear in a numeric because the parser +uses them for other purposes: NUL, space, `:`, `+`, `&`, `#`, `$`, `@`, `%`. + +### 2.2 Server numerics + +A server numeric is two characters, i.e. a value in 0..4095 (`AA`..`]]`). +Every server on the network must have a distinct numeric. A server's numeric +is configured locally and announced in its `SERVER` line. + +### 2.3 Client numerics + +A client numeric is three characters (0..262143) that are unique on the +owning server. The network-wide identifier of a user is the concatenation +``, five characters. + +Each server also announces a *capacity mask* in its `SERVER` line as three +base64 characters (`nn_capacity`). The mask is always one less than a power +of two and at least 15. A server may hand out client numerics larger than +its mask; receivers index their per-server client table with +`numeric & mask`. The extra bits give a server some slack so that a numeric +freed a moment ago is not immediately reused (which could misdeliver +in-flight messages). If a `NICK` introduces a numeric whose masked slot is +already occupied, the *old* occupant is exited with the reason +"Numeric nick collision (Ghost)". + +This server allocates local numerics round-robin from a counter, skipping +occupied slots. + +### 2.4 IP address encoding + +Client IP addresses in `NICK` are base64 encoded: + +- An IPv4 address (including IPv4-mapped IPv6) is the 32-bit host value + written as exactly six base64 characters, e.g. `127.0.0.1` = `B]AAAB`. +- An IPv6 address is written as eight groups of three base64 characters + (one per 16-bit segment). The longest run of zero segments is replaced by + a single `_`. Example: `2001:db8::1` becomes `CAB` `A24` `_` `AAB` + concatenated as `CABA24_AAB`. +- When the peer did not announce IPv6 support (no `6` server flag), an IPv6 + client is sent as the six-character form: for 6to4 (`2002::/16`) the + embedded IPv4 address, otherwise `AAAAAA` (0.0.0.0). + +On decode, a six-character string is an IPv4 address (an all-zero value +stays 0.0.0.0 rather than `::ffff:0.0.0.0`); anything else is parsed as the +IPv6 form. + +Worked examples (all values verified against `iptobase64()`): + +| Address | To a peer with `6` | To a peer without `6` | +|---------|--------------------|------------------------| +| `127.0.0.1` | `B]AAAB` | `B]AAAB` | +| `192.0.2.5` | `DAAAIF` | `DAAAIF` | +| `2001:db8::1` | `CABA24_AAB` | `AAAAAA` | +| `2001:db8:15::` | `CABA24AAV_` | `AAAAAA` | +| `::1` | `_AAB` | `AAAAAA` | +| `::` | `_` | `AAAAAA` | +| `2002:c000:205::1` (6to4) | `CACMAAAIF_AAB` | `DAAAIF` (the embedded `192.0.2.5`) | + +The `_` may sit at the start, middle or end of the string, and an +unspecified address collapses to a single `_`. Only one run is ever +compressed; when two zero runs have the same length, the first one is +compressed and the other is written out as `AAA` groups. + +### 2.5 Timestamps + +Timestamps are decimal UNIX times. Any timestamp below `OLDEST_TS` +(780000000, roughly 1994-09) in a `SERVER` line is treated as bogus and +closes the link. Each server keeps a `TSoffset` that it adds to the local +clock to obtain the network's notion of time (`TStime()`); see `SETTIME`. + +--- + +## 3. Token table + +The command table from `include/msg.h` and `ircd/parse.c`, restricted to +the commands that take part in the S2S protocol. The "Server" column says +how a message arriving on a *server* link is handled: a handler name means +it has a dedicated server handler; *shared* means the same handler as for +clients is used. Client-only commands (`USER`, `ISON`, `LIST`, `WHO`, +`USERHOST`, `USERIP`, `CPRIVMSG`, `CNOTICE`, `MAP`, `HELP`, `CLOSE`, +`REHASH`, `RESTART`, `DIE`, `SET`, `RESET`, `GET`, `WEBIRC`, `CAP`, +`POST`, `AUTHENTICATE`) are not part of the protocol; a server that +receives one of them from a peer silently discards it, and they are +omitted below. + +| Command | Token | Server handling | Notes | +|---------|-------|-----------------|-------| +| PRIVMSG | `P` | `ms_privmsg` | | +| NICK | `N` | `ms_nick` | introduction and change | +| NOTICE | `O` | `ms_notice` | | +| TAGMSG | `TM` | `ms_tagmsg` | IRCv3 tag-only message | +| WALLCHOPS | `WC` | `ms_wallchops` | | +| WALLVOICES | `WV` | `ms_wallvoices` | | +| JOIN | `J` | `ms_join` | | +| MODE | `M` | `ms_mode` | channel and user modes | +| BURST | `B` | `ms_burst` | | +| CREATE | `C` | `ms_create` | | +| DESTRUCT | `DE` | `ms_destruct` | | +| QUIT | `Q` | `ms_quit` | | +| PART | `L` | `ms_part` | | +| TOPIC | `T` | `ms_topic` | | +| INVITE | `I` | `ms_invite` | | +| KICK | `K` | `ms_kick` | | +| WALLOPS | `WA` | `ms_wallops` | | +| WALLUSERS | `WU` | `ms_wallusers` | | +| DESYNCH | `DS` | `ms_desynch` | | +| PING | `G` | `ms_ping` | | +| PONG | `Z` | `ms_pong` | | +| ERROR | `Y` | `ms_error` | | +| KILL | `D` | `ms_kill` | | +| AWAY | `A` | `ms_away` | | +| SERVER | `S` | `ms_server` | `mr_server` for the link itself | +| SQUIT | `SQ` | `ms_squit` | | +| WHOIS | `W` | `ms_whois` | | +| WHOWAS | `X` | shared | | +| NAMES | `E` | shared | | +| TRACE | `TR` | `ms_trace` | | +| PASS | `PA` | ignored once registered | `mr_pass` before registration | +| LUSERS | `LU` | `ms_lusers` | | +| TIME | `TI` | shared | | +| SETTIME | `SE` | `ms_settime` | | +| RPING | `RI` | `ms_rping` | | +| RPONG | `RO` | `ms_rpong` | | +| OPER | `OPER` | `ms_oper` | legacy; converted to `MODE +o`, see 7.3 | +| CONNECT | `CO` | `ms_connect` | | +| VERSION | `V` | shared | | +| STATS | `R` | shared | | +| LINKS | `LI` | `ms_links` | | +| ADMIN | `AD` | `ms_admin` | | +| INFO | `F` | `ms_info` | | +| MOTD | `MO` | shared | | +| SILENCE | `U` | `ms_silence` | | +| GLINE | `GL` | `ms_gline` | | +| SLINE | `SL` | `ms_sline` | server only | +| JUPE | `JU` | `ms_jupe` | | +| OPMODE | `OM` | `ms_opmode` | | +| CLEARMODE | `CM` | `ms_clearmode` | | +| UPING | `UP` | `ms_uping` | | +| END_OF_BURST | `EB` | `ms_end_of_burst` | server only | +| EOB_ACK | `EA` | `ms_end_of_burst_ack` | server only | +| HASH | `HASH` | shared | | +| REHASH | `REHASH` | ignored | | +| RESTART | `RESTART` | ignored | | +| DIE | `DIE` | ignored | | +| PROTO | `PROTO` | shared | vestigial; REQ/ACK/SUP are parsed but do nothing | +| SET | `SET` | ignored | | +| RESET | `RESET` | ignored | | +| GET | `GET` | ignored | | +| PRIVS | `PR` | `ms_privs` | | +| ACCOUNT | `AC` | `ms_account` | server only | +| ASLL | `LL` | `ms_asll` | | +| WEBIRC | `WEBIRC` | ignored | | +| XQUERY | `XQ` | `ms_xquery` | | +| XREPLY | `XR` | `ms_xreply` | server only | +| CAP | `CAP` | ignored | | +| POST | `POST` | ignored | anti-proxy alias for QUIT on unregistered connections | +| AUTHENTICATE | `AUTHENTICATE` | ignored | client SASL; relayed via XQUERY | +| CONFIG | `CF` | `ms_config` | server only | + +`CHGHOST` has a token definition but no entry in the message table; it is a +client-facing capability message and is never accepted from a server. + +--- + +## 4. Link establishment + +### 4.1 Transport + +A server link is a TCP connection to a port configured as a server port. +If the Connect block or Port block is configured for TLS, the TLS handshake +completes *before* any P10 bytes are exchanged; there is no in-band STARTTLS. +On the accepting side the peer's certificate fingerprint and, optionally, +hostname are verified against the Connect block after `SERVER` is received. +A link established over TLS is marked with the `z` server flag when it is +announced to the rest of the network. + +### 4.2 PASS + +``` +PASS : +``` + +Sent unprefixed by the connecting side first (and by the accepting side in +its reply, if the Connect block has a password). If several parameters are +given they are re-joined with spaces. The password is compared to the +Connect block's password after `SERVER` is received. + +### 4.3 SERVER (self introduction) + +Sent unprefixed by each side to introduce itself. The connecting side sends +it right after `PASS`; the accepting side sends it in reply once the +incoming `SERVER` has been validated. + +``` +SERVER 1 J10 + : +``` + +| Field | Meaning | +|-------|---------| +| `` | The server's own name. Must be a valid host-style name (`clean_servername()`); a bogus name closes the link. | +| `1` | Hop count. Always 1 for a self introduction. | +| `` | When this ircd started (its "boot" timestamp). Used for clock reconciliation, see 4.5. | +| `` | The link timestamp. The connecting side picks `TStime()`, incremented until it is strictly greater than the link timestamp of every other server link it has, so link timestamps are unique per server. | +| `J10` | Protocol. `J` = still joining (has not completed its burst), `P` = burst complete. A self introduction is always `J`. The digits are the protocol version; a peer below `MINOR_PROTOCOL` (09) is rejected with "Incompatible protocol", a version above 10 is clamped to 10. | +| `` | The server numeric (first 2 chars) followed by its capacity mask (3 chars), see 2.3. | +| `+` | Server flags, see 4.6. This implementation sends `+h6` when it is a hub and `+6` otherwise. | +| `` | Free text. If empty the accepting side substitutes its own name. | + +At least 8 parameters are required. Validation on receipt (`mr_server`): + +1. The connection must not be on a client or WebSocket port. +2. The name is cleaned; if a Jupe is active for it the link is closed with + "Juped: ". +3. Connection rules (`CRULE_ALL`) are evaluated. +4. Protocol is parsed as above; both timestamps must be at least + `OLDEST_TS`. +5. There must be a Connect block for the name (`conf_check_server`), the + TLS fingerprint and hostname must match if configured, and the password + must match if configured. Failures close the link with a descriptive + `ERROR`. +6. Loop and hub/leaf checks (`check_loop_and_lh`, see 4.4). +7. The link is registered, the numeric installed, U:line config attached, + flags applied, clocks reconciled, and `server_estab()` runs (section 5). + +### 4.4 Loops, collisions, hubs and leaves + +`check_loop_and_lh()` runs for every `SERVER` (both direct introductions +and servers introduced behind a link). It enforces: + +- **Self collision**: a server introducing our own name is closed with + "nick collision with me". +- **Numeric collision**: if the numeric is already in use by a server with a + different name, a `WALLOPS` is broadcast and the link is closed with + "NUMERIC collision". +- **Name collision with a non-server**: closed with "Nickname already + exists". +- **Juped / second U:world**: a server whose existing entry has a + description starting with `JUPE`, or that matches a U:line, is refused + with the existing entry's description. +- **Duplicate server (real loop)**: when a server that already exists is + introduced again, the *second youngest* link on the two paths is squit. + The youngest link is kept because it is the one most recently + /CONNECTed; the second youngest is the one that closed the loop. If + timestamps tie, the loser is chosen by comparing server names. A server + that caused a ghost within the last 20 seconds is assumed to be a ghost + loop and the older instance is dropped instead. +- **Hub/leaf limits**: a leaf (feature `HUB` off) with an existing server + link refuses a second one ("I'm a leaf, define the HUB feature"). The + Connect block's `maxhops` and `hub` mask are enforced: introducing a + server beyond `maxhops` yields "Maximum hops exceeded", and a server not + matching the hub mask yields " is not allowed to hub for ". + Where possible the squit is targeted at the junction server that caused + the burst rather than the immediate link. + +Rejections of a *not yet registered* peer are sent as a bare +`ERROR :` and the socket is closed. Rejections of a server +introduced *behind* an established link are sent as +`SQUIT :` towards the link that introduced it +(`exit_new_server`). + +### 4.5 Clock reconciliation + +`check_start_timestamp()` compares the peer's start timestamp with ours: + +- With `RELIABLE_CLOCK` on: our start timestamp is lowered to the peer's if + the peer's is older, and the local clock is never adjusted. If, after the + link is up, the peer's link timestamp differs from our idea of now by more + than 30 seconds, a `SETTIME` with our time is sent to the peer. +- With `RELIABLE_CLOCK` off: if the peer started earlier, its clock wins and + `TSoffset` is adjusted by (its link-ts minus our receive time), with an + oper notice "clock adjusted by adding N". If start timestamps are equal + and the clocks differ, the *accepting* side's clock wins. + +### 4.6 Server flags + +The seventh `SERVER` parameter is `+` followed by zero or more of: + +| Flag | Meaning | +|------|---------| +| `h` | Hub. | +| `s` | Service (allows `nick@server` directed messages to it, see 9.3). | +| `6` | Understands base64 IPv6 addresses in `NICK`. Without it the sender uses the 6-character IPv4 form for every client. | +| `z` | The link between this server and its uplink is TLS. Used to compute secure-path groups for channel mode `+Z`/`+z`. | + +Unknown flag characters are ignored. In the original P10 document this +field was a fixed `0` placeholder; this implementation always sends `+` +plus flags. + +### 4.7 SERVER (introducing other servers) + +After registration, every other known server is described with a prefixed +`SERVER`: + +``` + S 0 10 + : +``` + +- The prefix is the numeric of the introduced server's *uplink*. +- `` is the hop count as seen from the sender plus one. +- The start-timestamp slot is always `0` for introduced servers. +- `J` means the introduced server is itself still bursting; `P` means it + has finished. During a burst the sender uses `J`/`P` based on the + `FLAG_BURST` state of each server; when relaying a newly seen `SERVER` it + copies the protocol field as received. +- The description must be non-empty ("No server info specified"). + +On receipt (`ms_server`) the same loop/hub checks run, a remote `Client` +structure is created under the sending server, its numeric is installed, +U:line config is attached and flags set. If the protocol field starts with +`J` the server is marked bursting and as a junction; a "Net junction" +notice is emitted if no server between it and us is already bursting. The +message is then relayed to every other local server link, except that a +server whose name matches our own name as a mask (`match(me, name)`) is +not relayed (domain-masked server names). + +### 4.8 ERROR + +``` +Y : +ERROR : +``` + +Sent when a link is closed by us: `Closing Link: by ()`. +Received `ERROR` is logged, shown to opers as +"ERROR :from -- ", and stored as the link's last error +(visible in `/STATS`). The unprefixed long form is used when the peer never +registered. + +--- + +## 5. The net burst + +When a link is established (`server_estab`), the local server sends its +entire view of the network to the new peer. The peer does the same in the +other direction; the two bursts are independent. Order of transmission: + +1. The new server is announced to all *other* local server links with a + `SERVER` line (section 4.7). Both sides mark the link as a *junction*. +2. **Global G-lines** (`GL`), **Jupes** (`JU`), **S-lines** (`SL`) and + network **CONFIG** entries (`CF`) are sent first so that the peer can + drop g-lined users and juped servers while still digesting the rest of + the burst. +3. **Servers**: every server known to us, except those reachable through + the new link, as `SERVER` lines (section 4.7). +4. **Users**: every user, as a `NICK` introduction (section 7.1). If the + feature `AWAY_BURST` is on (default), a user that is away is immediately + followed by an `AWAY` line from that user. +5. **Channels**: every non-local channel as one or more `BURST` lines + (section 8.1), followed by a `TOPIC` line if `TOPIC_BURST` is on + (default) and the channel has a topic. +6. `END_OF_BURST` (`EB`). + +While a peer is bursting it is marked `FLAG_BURST`; between its `EB` and +our `EA` it is `FLAG_BURST_ACK`. `IsBurstOrBurstAck()` is used in many +places to relax checks (for example, lag is not estimated from timestamps +in bursts, kicks from bursting servers do not generate HACK notices, and +channel messages are not delivered to users behind a bursting link, +`SKIP_BURST`). + +### 5.1 END_OF_BURST and EOB_ACK + +``` + EB + EA +``` + +On receiving `EB` from a server, the receiver: + +- emits "Completed net.burst from ", +- relays `EB` to all other links, +- clears `FLAG_BURST` and sets `FLAG_BURST_ACK` on that server, +- if the server is a direct link, replies with `EA`, +- sweeps channels: any channel that was created by this burst + (`MODE_BURSTADDED`) and has no members is destroyed; the flag is cleared + on all others. + +On receiving `EA` the receiver relays it to other links and clears +`FLAG_BURST_ACK` on the sender. The full handshake for a link between S1 +and S2 is therefore: + +``` +S1 -> S2 : PASS, SERVER +S2 -> S1 : PASS, SERVER +S1 -> S2 : GL/JU/SL/CF..., S..., N..., B..., EB +S2 -> S1 : GL/JU/SL/CF..., S..., N..., B..., EB +S2 -> S1 : EA +S1 -> S2 : EA +``` + +`EB` and `EA` are also relayed through the network so that every server +learns when a remote junction has finished bursting. + +--- + +## 6. Server and link management + +### 6.1 SQUIT + +``` + SQ : +``` + +- `` may be a server name or numeric. +- `` must equal the link timestamp of the server being removed, + otherwise the message is a stale duplicate and is ignored. A timestamp of + `0` forces the squit regardless (used when a server squits its own direct + link). +- If the target is the receiving server itself, the message is reversed: + the link it came from is closed instead. + +Generation: when a server is removed (`exit_client`), every other link +receives `SQ :` from the killer, and all +users behind that server are removed locally *without* individual `QUIT` +lines being sent (a receiver must walk the tree itself). If the victim is +our direct link, it is sent `SQ 0 :` followed by +`ERROR :Closing Link ...` before the socket is closed. + +A missing timestamp is a protocol violation but is still processed. + +### 6.2 PING and PONG + +Servers send a keepalive when `max_ping` has elapsed without traffic. The +AsLL (as-lag-as-latency) form is used on server links: + +``` + G ! + Z +``` + +- `G`: parameter 1 is `!` followed by the sender's timestamp with + millisecond fraction, parameter 2 is the target server name, parameter 3 + repeats the timestamp. The `!`-prefixed origin lets a non-AsLL server + echo it back as a normal PONG so RTT can still be measured. +- `Z` (AsLL reply, 5 parameters after the prefix): origin numeric, the + origin string from the ping, the timestamp received, the one-way + difference in milliseconds as computed by the responder, and the + responder's own timestamp. The receiver stores round-trip time, and the + to/from one-way estimates, on the link (`/STATS l`, `ASLL`). + +Example. Hub `AF` pings leaf `AB`; the leaf's clock says the ping took +4 ms to arrive, and the hub computes the round trip from the echoed +timestamp in the third reply parameter: + +``` +< AF G !1268659458.161 leaf.example.net 1268659458.161 +> AB Z AB !1268659458.161 1268659458.161 4 1268659458.165 +``` + +Note that the second reply parameter is the origin string copied +verbatim, still carrying its `!`. + +Legacy forms are also handled: + +``` + G [] + Z : +``` + +A `PING` with a destination that is not us is forwarded to that server +(`G :`); otherwise a `PONG` `Z :` +is returned to the server the ping came from. A `PONG` whose destination is a user numeric is delivered to that +user's server; one whose destination starts with `!` carries a timestamp +from a non-AsLL responder and updates only RTT. + +A link that has not answered within twice `max_ping` is closed +("Ping timeout"). + +### 6.3 SETTIME + +``` + SE [] +``` + +Sets the network clock. Without a target it is flooded to all links +(high-priority queue). With a target it is routed via `hunt_server`. On the +final recipient: + +- With `RELIABLE_CLOCK` off, `TSoffset` is adjusted so that `TStime()` + equals ``, and opers are told "clock is set N seconds + forwards/backwards". +- With `RELIABLE_CLOCK` on, the clock is *not* changed. The server rewrites + the timestamp in the relayed message to its own time, and if the delta + exceeds 600 seconds it broadcasts `DESYNCH :Bad SETTIME from ...`. If a + routed `SETTIME` merely passes through a reliable-clock server and the + delta exceeds 30 seconds, a corrected `SETTIME` is bounced back to the + sender. + +A `SETTIME` with a timestamp below `OLDEST_TS` or more than 9 000 000 +seconds in the future is a protocol violation. Servers also emit `SETTIME` +spontaneously when a `CREATE` arrives whose timestamp is more than a minute +ahead of local time, and on link-up when `RELIABLE_CLOCK` sees a 30-second +skew (4.5). + +### 6.4 RPING and RPONG + +Remote round-trip measurement, oper-initiated. + +``` + RI : (oper -> start server, via hunt_server) + RI : (start server -> target) + RO : (target -> start server) + RO : (start server -> oper's server) +``` + +The start server stamps its time, the target replies with the same stamp +plus its own, the start server computes the round trip and forwards a +4-parameter `RO` to the requesting user, whose server renders it as a +notice. `RI`/`RO` are only accepted from privileged sources; `RO` only from +servers. A server-originated `RI` updates the lag estimate of the +forwarding server from the embedded timestamp. + +### 6.5 UPING + +``` + UP +``` + +Routed to `` with `hunt_server`; the target sends UDP pings +to `` (which must be in its Connect blocks) and reports results to +the requester with `NOTICE`. Requires oper status. + +### 6.6 ASLL + +``` + LL + LL +``` + +Requests the AsLL statistics of the target's local links matching the mask. +Replies are relayed hop by hop until they reach the requester's server, +which formats them; a final `NOTICE` gives the match count. Sent on the +priority queue. + +### 6.7 CONNECT + +``` + CO +``` + +Routed with `hunt_server`. The target evaluates its Connect blocks, +connection rules and Jupes, announces "Remote CONNECT ..." via `WALLOPS` +and attempts the connection. `` of `0` means the configured port. + +### 6.8 WALLOPS and WALLUSERS + +``` + WA : + WU : +``` + +Oper- and user-directed broadcasts. Each is relayed to all other links +and delivered locally to users with umode `+w` (`WALLOPS` to opers only +if `HIS_WALLOPS` is on). Local recipients see `WALLOPS :* text` (`WA`) +and `WALLOPS :$ text` (`WU`). + +### 6.9 DESYNCH + +``` + DS : +``` + +A diagnostic broadcast that servers generate themselves when they detect +a protocol inconsistency (for example a bad `SETTIME`, see 6.3). Relayed +to all other links; delivered locally to users with umode `+g` as +`WALLOPS :text`. + +--- + +## 7. Users + +### 7.1 NICK (introduction) + +``` + N [+ [...]] : +``` + +| Field | Meaning | +|-------|---------| +| prefix | The numeric of the server the user is on. | +| `` | Nickname. Must pass `do_nick_name()` unchanged, otherwise the introducing server is sent a `KILL` for the numeric and the user is not created. Truncated at the compile-time `NICKLEN` (15). | +| `` | Hop count from the sender, plus one. | +| `` | Nick timestamp: the time the user connected, or of the last nick change. Also used for lag estimation outside bursts. | +| `` | Username (ident or `~`-prefixed). | +| `` | The user's real hostname. Host hiding is applied by each server locally; the wire always carries the real host. | +| `+` | Optional. Present if and only if the seventh parameter starts with `+`. Only *global* user modes are sent (see 15.2); `+o` is omitted unless the oper has the `PROPAGATE` privilege. | +| `` | One extra parameter per mode that takes an argument, in mode-character order: `r` takes `[:[:]]`, `z` takes the TLS certificate fingerprint or `_` (only when `NETWORK_FEATURES` is on). | +| `` | Base64 IP (2.4). Always the third-from-last parameter. | +| `` | The user's numeric. Always the second-from-last parameter. | +| `` | GECOS. | + +A server-originated `NICK` requires at least 8 parameters. Example: + +``` +AB N Mr_Foo 1 947957852 ~me myhost.example.net +diwr foo:1234:5 B]AAAB ABAAA :Mr Foo +``` + +Processing (`ms_nick` then `set_nick_name`/`register_user`): + +- The user is added under the introducing server. If the numeric slot is + already occupied, the old occupant is exited (2.3). +- Direction check: the user's server must be reachable through the link the + message arrived on; otherwise `KILL : ( != )` + is sent back and the user is dropped. +- IP-based connection limiting (`IPcheck_remote_connect`) may reject the + user; it is then killed with "Too many connections from your host -- + Ghost". +- The `NICK` is relayed to all other links. Peers that announced `6` get + the full IPv6 form; others get the 6-character form. +- If the account umode was present, the account name, numeric id and flags + are stored and host hiding applies as if `ACCOUNT` had been received. + +### 7.2 NICK (change) + +``` + N +``` + +`` is the time of the change and becomes the user's new nick +timestamp. Nick collisions are handled as described in 14.1. A bad nick +change results in a network-wide `KILL` of the user. + +### 7.3 MODE (user modes) + +``` + M :<+|-> [...] +``` + +- The target is the user's *nick name* (not numeric), and must be the + message source itself; otherwise a `WALLOPS` "MODE for User X from Y" is + emitted and the message dropped. +- Mode characters and their meaning are in 15.2. `+r ` + sets the account (there is no `-r`); `+z []` sets the TLS + flag (the fingerprint argument only exists when `NETWORK_FEATURES` is on, + and a value of `_` means "no certificate"); `+x` enables host hiding. +- A server may set any mode. Changes are relayed to all other links (with + `+o` only if the user has the `PROPAGATE` privilege) and, for local + users, echoed to the user. + +A legacy `OPER` arriving on a server link for a user that is not already +an oper also ends up here: `ms_oper` marks the user `+o` and propagates +`MODE :+o` to the other links. The `OPER` message itself is +consumed at that hop and never relayed; oper status only ever travels +the network as `MODE`. + +### 7.4 ACCOUNT + +``` + AC [ []] +``` + +Sets the services account of a user. Only accepted when the originating +server (or, failing that, the link it arrived on) matches a `UWorld` block; +otherwise it is a protocol violation. + +- `` is at most `ACCOUNTLEN` (12) characters for a first + assignment. +- `` is a 64-bit numeric account id, `` a 64-bit flag word. +- The account name cannot be changed once set: a second `ACCOUNT` with a + different name is a protocol violation. A second `ACCOUNT` with the same + name may supply an id (adopted if the stored id was 0) and update the + flags. +- On first assignment the user gets umode `+r`, host hiding is applied, + and clients with `account-notify` on common channels are informed. +- Propagation: the first `ACCOUNT` for a user is always relayed, in the + shortest form that carries the received fields. Same-name updates for an + already-authenticated user are relayed only when `NETWORK_FEATURES` is + on, because older ircu versions treat any second `ACCOUNT` as a + protocol violation. + +For a user that arrives during a burst the same information travels inside +the `NICK` umode string (`+r account:id:flags`). + +### 7.5 AWAY + +``` + A : + A +``` + +The first form marks the user away, the second clears it. Relayed to all +other links. A server as source is a protocol violation. During a burst +(with `AWAY_BURST`) an `A` line follows each away user's `NICK`. + +### 7.6 QUIT + +``` + Q : +``` + +Removes a user. Relayed to all other links (unless the user was killed, in +which case the `KILL` already did that). A server as source is a protocol +violation ("Server QUIT, not SQUIT?"). When a server splits, no `QUIT`s are +sent for its users; the `SQUIT` implies them. + +### 7.7 KILL + +``` + D : +``` + +- `` is the victim. +- The trailing parameter is a path (names joined by `!`) followed by a + space and the human-readable reason. An oper-issued kill starts with the + path `!`, and every server that relays the kill + prepends the name of the link it received it from: + `!`. On receipt everything up to the first + space is the path, the rest is the reason; a missing reason becomes + "(No reason supplied)". +- If the victim is unknown, a user source gets a `NOTICE` "KILL target + disconnected before I got him" and the message is dropped. +- The kill is applied by `do_kill`: the victim is exited with + "Killed ( )", the message is relayed to all other links + with the extended path, and the victim (if local) sees the kill as + coming from the HIS server name if `HIS_KILLWHO` is on. + +**The ghost bounce.** Whenever the victim of a received `KILL` is a +*local* user, the receiving server first sends a kill for the same +numeric *back* to the link the message arrived on: + +``` +< AFAAB D ABAAC :hub.example.net!admin.example.net!oper spamming +> AB D ABAAC :hub.example.net!admin.example.net!oper (Ghost 5 Numeric Collided) +``` + +This defends against a `KILL` crossing a `NICK` that reuses the numeric. +The scenario, from the comment in `ms_kill()`: + +``` + KILL SAA --> X + <-- S NICK ... SAA | <-- SAA QUIT <-- S NICK ... SAA <-- SQUIT S +``` + +A kill for `SAA` travels right while, on the same link, server `S` splits +off, taking the original `SAA` with it, and is then reintroduced together +with a *new* user that was assigned the same numeric `SAA`. If the kill +reaches point `X` after the SQUIT but before the second introduction has +been processed everywhere, the original kill never reaches the right-hand +side (the SQUIT removed its path), the crossing `QUIT` of the old user is +ignored (the victim already has `FLAG_KILLED` set), and the second +`NICK ... SAA` would leave a ghost on the servers that already applied +the kill. The bounced kill cleans that ghost up. The bounce is harmless +when there was no race: if the next hop no longer knows the numeric, the +bounce is dropped there and propagates no further. + +`KILL` is one of the messages allowed to travel against an SQUIT +(section 1.2). Servers also generate `KILL`s for nick collisions (14.1), +bad nicknames, direction errors and numeric collisions. + +### 7.8 SILENCE + +``` + U <[+|-][~]mask>[,...] +``` + +- `` is `*` (broadcast to all servers) or the numeric of a specific + user; in the latter case the update is sent only towards that user's + server (used when a silenced user needs to learn about an existing + silence). +- Each mask is prefixed by `+` (add, default) or `-` (remove) and may carry + `~` for an exception entry. Masks are canonicalised (`pretty_mask`) and + may be CIDR. +- A server source is a protocol violation. + +Propagation is selective: a server only forwards a `+` silence downstream +when the target side has not yet seen it, so silence lists are lazily +distributed. + +### 7.9 PRIVS + +``` + PR [ ...] +``` + +Requests the oper privilege list of the named users. Each numeric that +belongs to a local user is answered with `RPL_PRIVS` numerics to the +requester; others are forwarded to the owning server. + +### 7.10 OPMODE for users + +``` + OM +o | -o | +x +``` + +A U:lined server may remotely oper (`+o`, requires the `oper` form of the +`UWorld` block), de-oper (`-o`) or force host hiding on a user that has an +account (`+x`). The message is relayed towards the user's server; `+x` is +relayed only when `NETWORK_FEATURES` is on. Any other mode is ignored. + +--- + +## 8. Channels + +Channel names starting with `#` are global; `&` channels are local to a +server and never appear on server links. Names are at most `CHANNELLEN` +(200) characters. Every global channel has a *creation timestamp*; the +lower value always wins in conflicts (section 14.2). + +### 8.1 BURST + +``` + B <#channel> [+ [...]] [] [:% [...]] +``` + +A `BURST` describes the complete state of a channel as known by the +sending server. It is generated during a net burst and also outside of it +(in reply to a `DESTRUCT` that crossed a join, see 8.10). A channel whose +description does not fit in one line is continued in further `BURST` +lines for the same channel and timestamp; continuation lines never +contain the mode block. + +**Modes.** The mode block is `+` followed by the simple mode letters in +the order `s|p m t i n r D R c C u M Z` (see 15.1), then `l`, `k`, `A`, `U`. +Arguments follow in the same order: limit, key, admin pass, user pass. The +real key and passwords are sent to servers (clients see `*`). + +**Member list.** A comma-separated list of user numerics, each optionally +followed by `:` and a status specifier. A specifier applies to that numeric +and all following numerics until the next specifier. Members are emitted +in four groups, in this mandatory order: no status, voice only, op only, +op and voice. Within the two opped groups members are sorted by increasing +op level. + +Specifier syntax: + +| Specifier | Meaning | +|-----------|---------| +| `:v` | Voice. | +| `:o` | Channel op with no op-level information (level `MAXOPLEVEL`, 999). Used when no member of the channel has a real op level. Older peers may send `:ov`. | +| `:` | Channel op. In the *first* digit-only specifier of a `BURST` line, and in any specifier that also contains `v`, `` is the absolute op level (0..999). In a later digit-only specifier, `` is an *increment* relative to the previous op level. | +| `:v` | Voice and op with absolute level ``. | + +A complete example (verified against the encoder in +`send_channel_modes()`): channel `#test`, created at 1721000000, modes +`+tink`, one ban, eight members: + +``` +AF B #test 1721000000 +tink akey ABAAB,AFAAC:v,AFAAD,ABAAA:0,AFAAE,AFAAG:2,ABAAC:v1,AFAAF:3 :%*!*@spam.example.net +``` + +| Members | Decoded status | +|---------|----------------| +| `ABAAB` | none | +| `AFAAC`, `AFAAD` | voice (`:v` carries to `AFAAD`) | +| `ABAAA`, `AFAAE` | op at level 0 (`:0` is absolute — first digit-only specifier) | +| `AFAAG` | op at level 2 (`:2` is an increment over the previous level 0) | +| `ABAAC` | op and voice at level 1 (`:v1` contains `v`, so `1` is absolute) | +| `AFAAF` | op and voice at level 4 (`:3` increments the previous level 1) | + +When no member of the channel has a real op level, no levels are sent at +all: opped members get `:o` and opped+voiced members get `:vo`, again +carrying to the following numerics. + +If the channel does not fit in one line, the same state may arrive split +across continuation lines: + +``` +AF B #test 1721000000 +tink akey ABAAB,AFAAC:v,AFAAD,ABAAA:0,AFAAE,AFAAG:2 +AF B #test 1721000000 ABAAC:v1,AFAAF:3 :%*!*@spam.example.net +``` + +A continued line carries no mode block, restarts op levels with an +absolute value, and always repeats the current status specifier on its +first member unless the current status is "none". The ban list rides on +whichever line has room after the last member (and can spill onto further +continuation lines by itself). + +**Bans.** The last parameter, if it starts with `%`, is a space-separated +ban list. The receiver canonicalises each ban, drops those already present +or covered by an existing ban, and marks existing bans that the new one +covers for removal. + +**Processing** (`ms_burst`). Let `T` be the receiver's creation time for +the channel (0 if the channel is new). + +- The channel is created if it does not exist and is marked + `MODE_BURSTADDED` so that it can be cleaned up at `EB` if it ends up + empty. +- *Zannel handling*: an empty channel is sent as a `BURST` with only three + parameters. If our side has users and the incoming timestamp is between + `T-4` and `T-1`, we keep our own timestamp (do not deop our users for a + channel that was merely cycled during a split). Symmetrically, if we are + the empty side and the incoming timestamp is up to 4 seconds newer, we + adopt it so both sides converge. +- If the incoming timestamp is *older* than `T`: all our modes, bans, + ops and voices are wiped (a `MODE -...` is shown to local users), the + topic is cleared, and *net-ride protection* runs first: if the incoming + channel is `+i` (and the local member is not an oper), `+r` (and the + member has no account), `+Z` (and the member is not on TLS), or `+k` + with a different key, every local member is kicked with "Net Rider" + (`KICK` is sent to all servers and the member becomes a zombie). +- If the timestamps are equal, the incoming modes, ops, voices and bans + are *added* to ours. +- If the incoming timestamp is *newer*, the burst is applied for + membership only: members are joined but every mode, status and ban in + the message is ignored, and the relayed `BURST` carries our timestamp and + no modes. +- Members that cannot be found, or that are not behind the link the burst + came from, are skipped. Members already on the channel (from a `CREATE` + or `JOIN` that raced the burst) keep their status and have it merged. +- A `+D` channel joins bursted members as delayed (hidden) unless they + have status. +- The `BURST` is then relayed to all other links, rebuilt from what was + actually accepted, and the resulting mode changes are shown to local + channel members as a `MODE` from the server (or from the HIS server name + if `HIS_MODEWHO`). + +**Topic.** After the last `BURST` line for a channel, the sender emits +`TOPIC` (8.6) if the channel has a topic and `TOPIC_BURST` is on. + +### 8.2 CREATE + +``` + C <#chan>[,<#chan>...] +``` + +A user has created one or more channels at time `` and is the (only) +op. Generated when a local user joins a channel that does not exist. + +Processing (`ms_create`): + +- A server as source is a protocol violation. Lag is estimated from `` + outside bursts; a timestamp more than 60 seconds in the future triggers a + `SETTIME` towards that server (rate limited). +- If the channel does not exist it is created with `` and the user is + joined with ops. The `CREATE` is relayed. +- If the channel exists: a `CREATE` for a channel the user is already on is + a protocol violation. If `` is more than a day old (`TS_LAG_TIME`), + or newer than our creation time for a non-empty (or `+A`) channel, the + op is *bounced*: outside a burst a `MODE -o ` is sent back to + the originating link as a HACK(2), the user is joined without ops and a + `JOIN` (not `CREATE`) is relayed; during a burst the user is simply + joined without ops if the timestamps differ by more than 4 seconds. + Otherwise our creation time is overwritten with `` and the user is + joined with ops. + +`CREATE` lines carry up to `MAXJOINARGS` (15) channels. + +### 8.3 JOIN + +``` + J <#chan>[,<#chan>...] + J 0 +``` + +A user joins existing channels; `` is the creation time of the channel +as known by the sender. `J 0` means "part all channels" and is generated by +a client `JOIN 0`. This server sends one channel per `J` line, but accepts +lists. + +Processing (`ms_join`): + +- Local (`&`) channels and invalid names are protocol violations and + skipped. +- If the channel does not exist it is created with `` and the user + joined without status. +- If `` is older than our creation time, or the channel is empty + without `+A`, our creation time is replaced and *all* current modes, key, + limit, passes, ops and voices are wiped with a HACK(3) `MODE`. This is + what synchronises creation times across the network and prevents net + rides via empty channels. +- The join is relayed to other links and shown to local channel members. + With `+D` and no status the join is delayed (not shown). + +### 8.4 PART + +``` + L <#chan>[,<#chan>...] [:] +``` + +Removes the user from the listed channels; channels the user is not on, +local channels and unknown channels are ignored. Relayed with the same +list; local members see individual `PART`s, except that no `PART` is shown +for a zombie or a hidden (delayed-join) member. + +### 8.5 KICK + +``` + K <#chan> : +``` + +Processing (`ms_kick`): + +- If the channel or victim is unknown the message is dropped. A kick for a + user that is not on the channel is still relayed (the kick may have + crossed a join). +- If the kicked member is already a zombie and the kick comes from the + victim's own server, the membership is finally removed. +- A kick from a server that is neither bursting nor the victim's own + server produces a HACK(4) notice. +- *Bounce*: if the kicker is a user who is not opped on the channel here, + and the victim is not behind the link the kick came from, the kick is + rejected: the victim is re-introduced to the sending link with a `JOIN` + and, if they had status, a bounced `MODE` that re-ops/re-voices them and + deops the kicker (HACK(2)). +- Otherwise the kick is relayed, shown to local members (with the HIS + server as source if the kicker is a server) and the member is made a + *zombie*: it stays in the channel structure until its own server confirms + with a `PART`/`KICK`, so that a crossing message from the victim can + still be matched. Zombies do not receive channel traffic. + +### 8.6 TOPIC + +``` + T <#chan>[,<#chan>...] [ [ []]] : +``` + +This implementation always sends the five-parameter form +`T <#chan> :`. On receipt: + +- If `` is given and is newer than our creation time, ignore + (topic set on a younger instance of the channel). +- If `` is given and is older than our topic time, ignore. +- `` (a nick name) becomes the recorded topic setter; if absent, + the source's name (or the HIS server name for server sources when + `HIS_BANWHO` is on) is used. +- The topic is relayed with our creation time and the topic time, and + shown to local members only if the text actually changed. + +### 8.7 MODE (channel modes) + +``` + M <#chan> [...] [] +``` + +- `` uses `+`/`-` with the letters in 15.1. Up to + `MAXMODEPARAMS` (6) argument-taking modes per message. +- `o`/`v` arguments are user numerics. For `+o` the argument may carry an + op level as `:`; this is sent when the level is below 999. +- `b` arguments are ban masks, `k` a key, `l` a decimal limit, `A`/`U` the + admin/user pass. +- A trailing decimal parameter is the channel creation timestamp; it is + appended by this implementation on every relayed channel `MODE` and on + bounced modes. On receipt from a server link it is compared with our + creation time: an *older* timestamp is adopted (the sender knows an older + instance of the channel); a *newer* one means the sender is desynced, so + the mode is bounced back with our timestamp and, for a user source, the + user is deopped (HACK(2)). If the sender is still bursting, the newer + timestamp is assumed to be a not-yet-processed burst and the mode is + silently dropped instead of bounced. + +Processing (`ms_mode`): + +- If the target is not a channel it is treated as a user mode change + (7.3). Local channels are ignored. +- Source is a **server**: the mode is forced. If the server is U:lined a + HACK(4) notice is shown; otherwise with `OPLEVELS` off a HACK(3) notice + is shown. With `OPLEVELS` on no notice is generated because servers must + be able to op users who joined with the `+A`/`+U` passes. +- Source is a **user who is opped** here: the mode is applied and relayed. +- Source is a **user who is not opped** (or not a member): the mode is + *bounced*. Nothing is applied; a `MODE` with the opposite sense, a + `-o ` deop, and our creation timestamp is sent back on the link + it came from, and a HACK(2) notice is shown. Bounced messages come from + the server itself as source. + +Relayed modes are sent as `M <#chan> `. Local +users see the change as coming from the source, or from the HIS server +name for server sources when `HIS_MODEWHO` is on. + +Examples as relayed between servers (channel created at 1721000000): + +``` +ABAAA M #test +tk sekret 1721000000 +ABAAA M #test +o ABAAB 1721000000 +ABAAA M #test +o ABAAB:2 1721000000 +``` + +The first op is granted at the default level 999, so no `:` suffix +is sent; the second carries an explicit op level 2. + +A bounce, on the wire: our creation time is 1721000000 and `ABAAA` is not +opped here, so its `+m` (carrying a newer, desynced timestamp) is +reversed, a deop of the source is appended, and the result goes back +only on the link the mode came from, as coming from the server: + +``` +< ABAAA M #test +m 1721000500 +> AF M #test -mo ABAAA 1721000000 +``` + +Modes with special S2S handling: + +- `+Z`: requested TLS-only. If not every member is on the same secure path + group, the server sets `+z` (insecure) locally instead but still relays + `+Z`; servers only ever exchange `Z`. Local clients see `z`. +- `-D` when hidden members exist becomes `+d` locally; `d` is never sent to + servers. +- `+s` and `+p` are mutually exclusive; setting one clears the other. +- `+R` (registered) cannot be changed by local users; servers may set it. + +### 8.8 OPMODE (channel) + +``` + OM <#chan> [...] +``` + +Same syntax as `MODE`, but the change is *always* forced regardless of the +source's channel status, relayed as `OM`, logged, and announced to opers as +HACK(4). Used by opers with the `OPMODE` privilege and by services. Local +users see the result as a `MODE` from the HIS server name. The trailing +timestamp is not appended to `OM`. + +### 8.9 CLEARMODE + +``` + CM <#chan> +``` + +Removes every listed mode from the channel in one operation: for `o`/`v` +all ops/voices, for `b` all bans, for `k`/`l` the key/limit, and any of the +simple flags. The resulting change is shown locally as an `OPMODE`-style +`MODE` from the server, relayed as `CM` with only the letters that actually +removed something, logged and announced as HACK(4). + +### 8.10 DESTRUCT + +``` + DE <#chan> +``` + +Announces that an empty channel expired (this server keeps empty +non-`+A` channels around as "zannels" for a while before destroying them). + +Processing (`ms_destruct`): + +- Unknown channel: ignore. `` newer than our creation time: ignore. +- If the channel is *not* empty here (a join crossed the destruct), the + message is not relayed; instead the channel is re-synchronised + *upstream* (to the link the `DESTRUCT` came from): a `PART` and then a + `JOIN` for every member, followed by a bounced `MODE` that re-applies all + ops, voices, modes, key, limit, passes and bans. (A `BURST` outside the + net burst would be the modern way, but `CREATE`/`JOIN`/`MODE` are used + for compatibility with older servers.) +- Otherwise the `DESTRUCT` is relayed to *all* links, including back to the + sender, and the channel is destroyed. + +### 8.11 INVITE + +``` + I <#chan> [] +``` + +- The invitee is given by *nick name*, the channel by name, and the + optional third parameter is the channel creation time. A server source + or a non-`#` channel is a protocol violation. +- If the channel does not exist the invite is still forwarded to the + invitee's server (to avoid join/invite/part abuse patterns). +- If `` is newer than our creation time the invite is ignored; + an invite without a timestamp is ignored while the link is bursting. +- The inviter must be on the channel unless it has umode `+k`; the invitee + must not be. Umode `+R` blocking and silence lists apply. +- For a local invitee the invite is recorded and delivered; otherwise it is + forwarded to the invitee's server with our creation time. Ops with + `invite-notify` on the channel are told, and with `ANNOUNCE_INVITES` + servers hosting channel ops receive a copy. + +--- + +## 9. Messaging + +### 9.1 PRIVMSG and NOTICE + +``` + P : + O : +``` + +`` on a server link may be: + +| Target | Handling | +|--------|----------| +| `` | A user numeric. Delivered to that user; silence lists, umode `+R` (unauthenticated sender) and umode `+c` (common channel required) are enforced on the *receiving* server too. If the user is gone, `ERR_NOSUCHNICK` "Target left . Failed to deliver: [...]" is returned to the sender. | +| `#channel` | Delivered to local members and relayed to every server that has members on the channel (deaf users and bursting links are skipped). The sender must be allowed to speak (`+n`, `+m`, `+M`, bans, `+c`/`+C` filters) unless it has umode `+k`. | +| `$mask` / `$@mask` | Oper broadcast to all users on servers matching `mask` (`$`) or hosts matching `mask` (`$@`). Only honoured if the source is an oper. | +| `nick[%host]@server` | Directed message to a *service*: the named server must have the `s` flag. Forwarded to that server, which delivers to a local user with umode `+k` whose nick (and optionally host) matches. Ordinary users are never reachable this way. | + +Fewer than 3 parameters: `PRIVMSG` is dropped silently, `NOTICE` is a +protocol violation. + +`CPRIVMSG`/`CNOTICE` never appear on server links; the originating server +converts them to `PRIVMSG`/`NOTICE`. + +### 9.2 TAGMSG + +``` +@ TM +``` + +An IRCv3 tag-only message with the same target forms as `PRIVMSG`. The +line is only sent to servers when `NETWORK_FEATURES` is on; when it is off, +inbound `TM` is still accepted and delivered to local clients that +negotiated `message-tags`. See section 13 for which tags survive the hop. + +### 9.3 WALLCHOPS and WALLVOICES + +``` + WC <#chan> : + WV <#chan> : +``` + +Delivered to channel ops (`WC`) or to voiced and opped members (`WV`), +respecting deaf users and bursting links, and relayed to servers with +matching members. Local recipients see `NOTICE @#chan :text` / +`NOTICE +#chan :text`. A non-user source is dropped. + +--- + +## 10. Network-wide policy + +G-lines, Jupes, S-lines and CONFIG entries are all versioned by a +*lastmod* timestamp so that bursts from two sides of a split can be +merged deterministically: the newer lastmod wins, an equal lastmod is a +no-op, and an *older* lastmod causes the receiver to resend its newer +record back to the sender (except during a burst, where a mismatch is +silently ignored). + +### 10.1 GLINE + +``` + GL [!][+|-|>|<] [] [] [] [:] +``` + +- `` is `*` for a global G-line or the numeric of a specific server + for a local one. +- `` is `user@host`, `user@ip/cidr`, `$Rrealname` or a `#channel` + (a BADCHAN G-line). The `!` prefix marks a forced (wide) G-line. +- Prefix `+` activates, `-` deactivates, `>` / `<` locally activate or + deactivate a global G-line on ``, and no prefix modifies an + existing G-line's expiry/reason without changing its state. +- `` is a *relative* lifetime in seconds from now (converted to an + absolute time on receipt; at most 7 days). +- `` is the modification timestamp used for merging. +- `` is an absolute timestamp after which the *record* may be + forgotten; it is monotonically increasing and at least the expiry, so a + deactivated G-line's history survives until then. + +Burst and propagation form for global G-lines: + +``` + GL * +user@host : + GL * -#badchan : +``` + +Handling on receipt follows `doc/readme.gline.md`: local G-lines targeted at +another server are forwarded to it (`GL [!]+mask +:`); local G-lines for us are created or destroyed; `>`/`<` for +another server are forwarded; global G-lines are created, modified, +activated or deactivated according to the prefix and lastmod. A global +activation/deactivation for a G-line we do not have and that carries no +expiry is relayed as-is (`GL * +mask `) even though we cannot +store it. Any accepted change is relayed with the full 7-field form from +`gline_propagate`. + +### 10.2 JUPE + +``` + JU [+|-] : +``` + +- `` is `*` (global) or a server numeric (local to that server; + forwarded there unchanged if it is not us). +- `+` active, `-` inactive. Jupes are never deleted, only deactivated. +- `` is relative seconds (at most 7 days), `` the version. +- A global Jupe replaces a local one of the same name. An active Jupe + causes any server of that name to be refused at link time and to be + squit if introduced. + +Burst form: ` JU * +juped.example.org 3593 955419707 :reason`. +Requires 6 parameters. + +### 10.3 SLINE + +``` + SL <+|-> : +``` + +Regex spam filters. `` here is an *absolute* timestamp (0 = never), +`` is `A` (all) or a combination of `P` (private), `C` (channel), +`L` (part), `Q` (quit), and `` is a regular expression. Unknown +type letters are a protocol violation. An existing S-line is updated only +if the incoming lastmod is newer and something (state, types or expiry) +actually changed; a rejected pattern is not propagated. Accepted changes +are relayed in the same form. Only accepted from servers. + +### 10.4 CONFIG + +``` + CF [:] +``` + +Network-wide dynamic configuration (`doc/readme.netconf.md`). A value sets or +updates the key if `` is newer than the stored entry; no value deletes +it. Accepted changes are relayed and announced to opers. All entries are +burst at link time. Known keys include `sasl.server`, `sasl.mechanisms`, +`sasl.timeout`, `sline.server` and `sline.hold_timeout`. Only accepted +from servers. + +--- + +## 11. Extension queries + +``` + XQ : + XR : +``` + +`XQUERY` is an opaque request from a server (or an oper, via the client +form) to a service server; `` is an opaque token the service must +echo in its `XREPLY`. `XREPLY` may only be sent by servers; `` is +either a server numeric or a user numeric (distinguished by length). Both +are forwarded hop by hop; a reply reaching its target server is dispatched +by the routing prefix: + +| Routing prefix | Used by | +|----------------|---------| +| `iauth:` | IAuth `X` requests (`doc/readme.iauth.md`); the reply is passed back to the iauth process. | +| `sasl:` | Client SASL. The server sends `SASL ` for a registered user, or `SASL ` for an unregistered one, then `SASL ` continuations. Replies are `SASL ` (relayed to the client as `AUTHENTICATE`), `OK[ ]` or `NO `. The SASL server is named by the `sasl.server` CONFIG key. | +| `spam:` | S-line hold queue: `spam: : :` is sent to the `sline.server`; the reply releases or blocks the held message. | + +Unknown routings are logged and dropped. `XQ`/`XR` never carry an +IRCv3 `@time` tag (section 13), because services parse them positionally. + +A worked SASL PLAIN example. An unregistered client on leaf `AB` sends +`AUTHENTICATE PLAIN`; the `sasl.server` CONFIG key names the services +server `AZ`. The leaf allocates cookie `7` and the following crosses the +server links (`>` sent by the leaf): + +``` +> AB XQ AZ sasl:7 :SASL 192.0.2.5 _ PLAIN +< AZ XR AB sasl:7 :SASL + +> AB XQ AZ sasl:7 :SASL AGZvbwBodW50ZXIy +< AZ XR AB sasl:7 :OK foo:42 +``` + +The first query carries the client's IP in text form and its TLS +certificate fingerprint (`_` = none) because the client is not yet +registered; for a client that authenticates after registration the first +query is `SASL ` instead. The `SASL +` reply is +relayed to the client as `AUTHENTICATE +`, the client's base64 response +comes back as a continuation query, and `OK foo:42` completes the login +with account `foo` (id 42); a failure would be `NO `. + +--- + +## 12. Remote queries and numeric relaying + +### 12.1 hunt_server routing + +Query commands accept a server parameter and are routed to it with +`hunt_server_cmd()`. A local user may give a server name, a wildcard mask, +or a nick (meaning that user's server). When the command is forwarded on a +server link the server parameter is rewritten as the *numeric* of the +destination server, and the reply comes back as numerics addressed to the +requester. If the destination has meanwhile split, the requester gets +`ERR_NOSUCHSERVER * :Server has disconnected`. + +Routed commands and their S2S shape (source is the requesting user): + +| Command | Forwarded as | +|---------|--------------| +| WHOIS | `W :` | +| WHOWAS | `X :` | +| STATS | `R :` or `R :` | +| LINKS | `LI :` | +| INFO | `F :` | +| ADMIN | `AD :` | +| LUSERS | `LU :` | +| MOTD | `MO ` | +| VERSION | `V :` | +| TIME | `TI :` | +| NAMES | `E <#chan> ` or `E -D <#chan> ` | +| TRACE | `TR :` (see `do_trace`) | +| SETTIME, RPING, UPING, ASLL, CONNECT | see section 6 | + +Remote `MOTD`, `VERSION`, `TIME`, `STATS` and `ADMIN` require oper status +when the `HIS_REMOTE` feature is on. + +### 12.2 Numeric replies + +A reply to a remote user is sent as: + +``` + +``` + +For example `AB 311 ACAAB Foo ~foo host.example.net * :Foo Bar`. + +On receipt (`do_numeric`): the source must be a server, the target is a +user numeric (or, for a few service bots, a channel name); if the target is +unknown or lives back through the sending link the message is dropped. +Numerics below 100 are remapped by adding 100 (they describe "this +connection" and are not meaningful remotely). The numeric is then +delivered to the target; if `HIS_REWRITE` is on and the target is not an +oper it is rewritten to appear to come from the local server. + +--- + +## 13. IRCv3 message tags on server links + +Server links accept an IRCv3 tag block at the start of any line. Tags are +parsed before the prefix and stored for the duration of the message, so a +tagged line is otherwise processed exactly like an untagged one; a peer +that does not know about tags would however misparse it, which is why +sending is gated. + +**Sending.** Tags are emitted on a server link only when `NETWORK_FEATURES` +is on. The block consists of: + +The only tag emitted on a server link is `time=`, sent when +`NETWORK_TIME` is on and the command is a client-visible event. An +upstream `time` is forwarded unchanged; otherwise the local time is +stamped. Commands that *never* carry `time`: `B`, `EB`, `EA`, `S`, `G`, +`Z`, `SE`, `LL`, `RI`, `RO`, `UP`, `PA`, `Y`, `PROTO`, `SQ`, `CF`, `JU`, +`GL`, `SL`, `XQ`, `XR`, `DE`. Example: + +``` +@time=2026-09-04T11:42:03.000Z ABAAA P #test :hello +``` + +Client-only (`+`-prefixed) tags and `account` are *never* federated: +`msg_tag_format_s2s()` strips them, so a `+draft/reply` or `+react` tag +reaches only clients local to the server that received it, and each +server adds its own `account` tag at the client edge. + +`TAGMSG` (`TM`) is only sent to servers when `NETWORK_FEATURES` is on. + +**Receiving.** Inbound tags are always parsed regardless of the feature +setting. Client-facing delivery adds `time` (from the upstream tag if +`NETWORK_TIME` is on, otherwise local delivery time) and `account` for +clients that negotiated those capabilities. + +--- + +## 14. Timestamps and conflict resolution + +### 14.1 Nick collisions + +When a `NICK` introduction or change names a nick that already exists: + +- If the existing entry is an unregistered local connection it is dropped + ("Overridden by other sign on") and the new nick wins. +- Otherwise the two are compared on `user@ip`: for an introduction, the + incoming `` and decoded `` against the existing user; for a + change, the two users' username and IP. +- **Different user@ip**: the *younger* nick (larger timestamp) is killed. + **Same user@ip** (the same person reconnected during a split): the + *older* one is killed, on the assumption that the newer connection is + live. +- **Equal timestamps**: both are killed. + +Killing the incoming introduction sends a `KILL` for its numeric back on +the link it came from only. Killing an existing user sends a network-wide +`KILL` with reason "overruled by older nick" or "nick collision from same +user@host", and the victim sees `ERR_NICKCOLLISION`. + +### 14.2 Channel timestamps + +The creation timestamp is the arbiter for every channel conflict: + +- A `BURST`, `JOIN` or `CREATE` carrying an *older* timestamp than ours + resets the channel: all modes, bans, ops and voices on our side are + removed (with a HACK(3) `MODE` shown locally) and the older timestamp is + adopted. +- A message carrying a *newer* timestamp is applied for membership only; + ops carried by it are ignored or bounced, and a `MODE` with a newer + channel timestamp than ours is bounced with our timestamp. +- Equal timestamps merge. +- An empty channel without `+A` accepts any incoming timestamp (there is + nothing to protect), and joins to an empty channel increment the + timestamp by one, which is why the burst logic tolerates a 4-second + window (8.1). +- Topics carry both the channel and the topic timestamp, so a topic from an + older channel instance or an older topic time is ignored. + +### 14.3 Net rides + +A net ride is gaining status on a channel during a split by exploiting +timestamp rules. Protections in this implementation: mode wipe on older +timestamp (above), "Net Rider" kicks when the older side is `+i`, `+k`, +`+r` or `+Z` (8.1), bouncing `CREATE`s newer than the channel, and the +zannel timestamp window that stops a user who merely cycled an empty +channel from being deopped. + +### 14.4 HACK notices + +Opers with snomask `HACK2`/`HACK3`/`HACK4` see: + +- **HACK(2)**: a user's mode or kick was bounced because they were not an + op here. The bounce is sent back with the channel timestamp. +- **HACK(3)**: a mode was forced by a timestamp reset, or a server set a + channel mode while `OPLEVELS` is off. +- **HACK(4)**: a mode/kick/clearmode/opmode from a server or U:lined + service. + +--- + +## 15. Reference tables + +### 15.1 Channel modes + +| Mode | Argument | S2S notes | +|------|----------|-----------| +| `o` | user numeric[:oplevel] | Op. | +| `v` | user numeric | Voice. | +| `b` | mask | Ban. Bans are burst in the `:%` list. | +| `k` | key | Key. Real key sent to servers. | +| `l` | number | Limit. Argument omitted when removing. | +| `A` | password | Admin pass (`OPLEVELS`). Real value sent to servers. | +| `U` | password | User pass (`OPLEVELS`). Real value sent to servers. | +| `p`, `s` | | Private / secret (mutually exclusive). | +| `m` | | Moderated. | +| `t` | | Topic limited to ops. | +| `i` | | Invite only (net-ride check). | +| `n` | | No external messages. | +| `r` | | Registered users only (net-ride check). | +| `D` | | Delayed joins. `d` (has hidden members) is local only. | +| `R` | | Registered with services; only servers may set it. | +| `c` | | No colours. | +| `C` | | No CTCP (except ACTION). | +| `u` | | No part messages. | +| `M` | | Moderate unauthenticated users. | +| `Z` | | TLS-only (net-ride check). `z` (insecure path) is local only; servers always exchange `Z`. | + +`BURST` mode order: `s|p`, `m`, `t`, `i`, `n`, `r`, `D`, `R`, `c`, `C`, +`u`, `M`, `Z`, then `l `, `k `, `A `, `U `. + +Op levels: 0 is the channel manager (creator with `+A`), joiners via `+U` +get 1, everyone else 999 (`MAXOPLEVEL`). A member can only deop members +with a level at or above their own. + +### 15.2 User modes + +| Mode | Global | Argument on S2S | Meaning | +|------|--------|-----------------|---------| +| `o` | yes | | IRC operator (sent only with `PROPAGATE` privilege). | +| `O` | no | | Local operator. | +| `i` | yes | | Invisible. | +| `w` | yes | | Receives WALLOPS/WALLUSERS. | +| `s` | yes | | Server notices (snomask is local). | +| `d` | yes | | Deaf: receives no channel traffic. | +| `k` | yes | | Channel service: cannot be kicked/deopped/killed, may speak anywhere, may invite without membership, reachable via `nick@server`. | +| `g` | yes | | Receives HACK and DESYNCH notices. | +| `r` | yes | `account[:id[:flags]]` | Has an account. Never removed. | +| `R` | yes | | Blocks messages from unauthenticated users. | +| `x` | yes | | Hidden host. | +| `z` | yes | `fingerprint` or `_` (with `NETWORK_FEATURES`) | Connected over TLS. Never removed. | +| `I` | yes | | Hide idle time. | +| `c` | yes | | Accept messages only from users on common channels. | + +Only *global* modes appear in `NICK` introductions and in relayed `MODE`s; +`O` is local. + +### 15.3 Length limits + +| Item | Limit | +|------|-------| +| Nick | 15 (compile-time `NICKLEN`) | +| Username | 10 | +| Host | 63 | +| Realname | 50 | +| Account | 12 | +| Channel name | 200 | +| Topic | 160 | +| Away message | 160 | +| Line body | 512 including CRLF | +| Tag block | 8191 (4094 of tag data from a server) | +| Mode parameters per MODE | 6 | +| Channels per JOIN/CREATE/PART line | 15 | +| G-line / Jupe expiry | 7 days | + +--- + +## 16. Example session + +Server `AB` (`leaf.example.net`) connects to hub `AF` +(`hub.example.net`). Lines marked `>` are sent by the leaf, `<` are +received. + +``` +> PASS :secret +> SERVER leaf.example.net 1 947957852 947957852 J10 AB]]] +6 :Example leaf +< PASS :secret +< SERVER hub.example.net 1 947901540 947958150 J10 AFAD] +h6 :Example hub +< AF GL * +*spam@*.example.org 3600 947958000 947961600 :Spam +< AF JU * +juped.example.net 3593 955419707 :Juped server +< AF CF 1711200000 sasl.mechanisms :PLAIN,EXTERNAL +< AF S services.example.net 2 0 947957585 P10 AZAD] +s6 :Services +< AF N Client1 1 947957573 ident userhost.net +oiwg B]AAAB AFAAA :Some client +< AZ N X 2 947957719 cservice services.net +kr X:1 AAAAAA AZAAA :Channel Service +< AF B #foobar 947957734 +tinlk 20 akey AZAAA,AFAAA:o :%*!*@*.ban.example +< AF T #foobar 947957734 947957800 Client1 :Welcome +< AF EB +> AB N MrFoo 1 947957852 ~me myhost.example.net +ir foo:42 B]AAAB ABAAA :Mr Foo +> AB B #mychannel 946101324 ABAAA:o +> AB EB +> AB EA +< AF EA +``` + +Steady-state traffic afterwards: + +``` +< AFAAA P ABAAA :hello +> ABAAA P #foobar :hi all +> ABAAA J #foobar 947957734 +< AFAAA M #foobar +o ABAAA 947957734 +> ABAAA T #foobar 947957734 947960000 MrFoo :new topic +> ABAAA N MrBar 947960100 +< AF G !947960200.123 leaf.example.net 947960200.123 +> AB Z AB !947960200.123 947960200.123 4 947960200.127 +< AZ AC ABAAA foo 42 0 +< AZ OM #foobar -o+v ABAAA ABAAA +> ABAAA Q :Leaving +< AF SQ services.example.net 947957585 :Services restarting +``` + +--- + +## 17. Compatibility notes + +- **Protocol versions.** `MINOR_PROTOCOL` is `09`, so P09 peers are + accepted in principle (their servers are flagged `FLAG_TS8` and their + `SERVER` protocol field is written as `J0`/`P0` + version when relayed), + but no P09 translation of numerics is performed by this tree; all + contemporary peers are P10. +- **`NETWORK_FEATURES`** (default on) gates every S2S extension an older + ircu2 cannot parse: TLS fingerprints as the argument of umode `+z` + (in `NICK` and `MODE`), remote `OPMODE +x`, `ACCOUNT` updates for users + who already have an account, IRCv3 tag blocks on server links, and + `TAGMSG`. Turn it off while mixed versions are linked; inbound + extensions are still accepted. +- **`NETWORK_TIME`** (default on) additionally gates the `time` tag. +- **`AWAY_BURST`** and **`TOPIC_BURST`** (both default on) control the + `AWAY` and `TOPIC` lines in the burst. +- **`OPLEVELS`** (default off) controls whether servers generate HACK(3) + notices for server-set channel modes; op levels themselves are always + parsed and burst. +- **`RELIABLE_CLOCK`** (default off) changes `SETTIME` and link-time clock + handling as described in 4.5 and 6.3. +- **Server name masking.** A `SERVER` for a name that matches the local + server's own name as a wildcard mask is not relayed to other links, and + users of such servers are burst through the masking server. This is the + legacy "domain masking" behaviour. diff --git a/doc/readme.asll b/doc/readme.asll deleted file mode 100644 index a48470b5..00000000 --- a/doc/readme.asll +++ /dev/null @@ -1,25 +0,0 @@ -AsLL preliminary documentation, last updated 13 Jun 2002 - -Server-to-server ping format: - - G ! - -prefix = origin server numeric -local-ts = local timestamp, as "seconds.miliseconds" -target = target server numeric - -The local-ts is also sent instead of the origin field, -so RTT information can be collected from non-AsLL servers, -while preserving backward compatibility. - - -Server-to-server pong format: - - Z - -prefix = origin server numeric -origin = origin server numeric -target = target server numeric -remote-ts = remote timestamp as received from an AsLL PING -diff = difference between local-ts and remote-ts in miliseconds (integer) -local-ts = local timestamp, as "seconds.miliseconds" diff --git a/doc/readme.cap.md b/doc/readme.cap.md new file mode 100644 index 00000000..77b80bd2 --- /dev/null +++ b/doc/readme.cap.md @@ -0,0 +1,66 @@ +# Client capabilities (`CAP`) + +## Overview + +ircu supports IRCv3 capability negotiation via the `CAP` command (`ircd/m_cap.c`, `include/capab.h`). +Clients can list, request, and clear capabilities before or after registration. +During registration on user or WebSocket ports, `CAP LS` / `CAP REQ` suspends auth until `CAP END`. + +Most capabilities are gated by a matching `CAP_*` feature (default `TRUE`). +Setting a feature to `FALSE` removes the capability from `LS`/`REQ` (see `doc/readme.features.md`). +`sasl` is special: it also depends on netconf and link state (see `doc/readme.sasl.md`). + +## Subcommands + +| Subcommand | Role | +| --- | --- | +| `CAP LS [302]` | List available capabilities. With `302` or higher, mark the client as IRCv3.2 (`FLAG_CAP302`), auto-enable sticky `cap-notify`, and include `name=value` for caps that have a value | +| `CAP LIST` | List capabilities the client currently has enabled | +| `CAP REQ :…` | Request enabling or disabling caps (`-cap` to clear). Success → `CAP ACK`; any failure → `CAP NAK` for the whole request string | +| `CAP END` | Finish CAP negotiation during registration (`auth_cap_done`) | +| `CAP NEW` / `CAP DEL` | Server→client only (clients do not send these). Used when availability changes for clients with `cap-notify` | + +`ACK` and `NAK` from clients are accepted as no-ops (protocol compatibility). + +Unavailable or feature-disabled caps are omitted from `LS` and cannot be `REQ`uest’d. +`CAPFL_PROHIBIT` / sticky flags also cause `NAK` (for example clearing sticky `cap-notify` on a 302 client). + +## IRCv3.2 notes + +- `CAP LS 302` sets `FLAG_CAP302` and enables `cap-notify` without listing it in `LS` (`CAPFL_HIDDEN_302`). +- `cap-notify` is sticky for 302 clients (`CAPFL_STICKY_302`): it cannot be cleared with `CAP REQ -cap-notify`. +- Dynamic availability changes call `cap_update_availability()`, which sends `CAP NEW` or `CAP DEL` to clients that have `cap-notify` (typically after SASL becomes available or disappears). + +## Supported capabilities + +| Capability | Feature | Notes | +| --- | --- | --- | +| `account-notify` | `CAP_ACCOUNTNOTIFY` | Account login notices | +| `away-notify` | `CAP_AWAYNOTIFY` | Away state changes | +| `chghost` | `CAP_CHGHOST` | Hidden host / trusted username changes | +| `echo-message` | `CAP_ECHOMESSAGE` | Echo of the client’s own messages | +| `extended-join` | `CAP_EXTJOIN` | Extended `JOIN` with account / realname | +| `invite-notify` | `CAP_INVITENOTIFY` | Invite notifications | +| `userhost-in-names` | `CAP_UHNAMES` | `user@host` in `NAMES` | +| `message-tags` | `CAP_MESSAGE_TAGS` | Client message tags; see tags section below | +| `server-time` | `CAP_SERVER_TIME` | `@time=` on delivered messages | +| `account-tag` | `CAP_ACCOUNT_TAG` | `@account=` on messages from logged-in users | +| `cap-notify` | *(none)* | Auto for `LS 302`; hidden from 302 `LS`; sticky | +| `sasl` | `CAP_SASL` | Starts unavailable until netconf + linked service; CAP value = mechanism list. See `doc/readme.sasl.md` | + +## Message tags + +With `message-tags` (and related caps), clients may send and receive IRCv3 message tags. + +- Server tags such as `time` and `account` are produced for clients that negotiated `server-time` / `account-tag` (or `message-tags` as applicable). +- Client-only tags (keys beginning with `+`) are filtered by feature `CLIENTTAGDENY` (ISUPPORT `CLIENTTAGDENY=…`). Default `"*"` denies all client-only tags; see `doc/readme.features.md`. +- S2S tag federation is controlled by `NETWORK_FEATURES` and `@time=` invention/forwarding by `NETWORK_TIME`. + +Implementation: `ircd/msg_tag.c`. + +## See also + +- `include/capab.h`, `ircd/m_cap.c` +- `doc/readme.features.md` (`CAP_*`, `CLIENTTAGDENY`, `NETWORK_FEATURES`, `NETWORK_TIME`) +- `doc/readme.sasl.md` +- IRCv3 capability negotiation: https://ircv3.net/specs/extensions/capability-negotiation diff --git a/doc/readme.crules b/doc/readme.crules deleted file mode 100644 index 803f06fa..00000000 --- a/doc/readme.crules +++ /dev/null @@ -1,126 +0,0 @@ -SmartRoute -Rule based connects -Draft 4 - Aug 19, 1994 -by Tony Vencill - -Rule based connects allow an admin to specify under what conditions -a connect should not be allowed. If no rules are specified for a -given C and/or N line it will be allowed under any condition. - -A rule may consist of any legal combination of the following functions -and operators. - -Functions ---------- -connected(targetmask) - true if a server other than that processing - the rule is connected that matches the - target mask -directcon(targetmask) - true if a server other than that processing - the rule is directly connected that matches - the target mask -via(viamask, targetmask) - true if a server other than that processing - the rule matches the target mask and is - connected via a directly connected server - that matches the via mask -directop() - true if an oper is directly connected - -Unary operators ---------------- -! eg: !argument - true if the argument is false - -Binary operartors ------------------ -&& eg: arg1&&arg2 - true if arg1 and arg2 are both true -|| eg: arg1||arg2 - true if arg1, arg2, or both are true - -Parenthesis () are allowed for grouping arguments, but if no parenthesis -are included, && will take precedence over ||, ! will take precedence -over both && and ||, and the function will be evaluated from left to -right. White space in a rule is ignored. Invalid characters in a rule -will lead to the rule being ignored. - -Examples --------- - -A simple example of a connect rule might be: - -connected(*eu.under*) - -This might be used in a US undernet server for a Europe CN pair to -insure that a second Europe link is not allowed if one US-EU link -already exists. Note that on the undernet, US server names are -city.state.us.undernet.org and Europe server names are -city.country.eu.undernet.org. - -A more interesting example might be: - -connected(*eu.under*) && - ( !direct(*eu.under*) || via(manhat*, *eu.under*) ) - -Imagine the Boston undernet server uses this rule on its Europe CN -pairs. This says that if a Europe server is already connected, a -Boston-Europe connect will not be allowed. It also says that if a -Europe server does already exist and Boston is not directly connected -to one or more Europe servers or Manhattan is, the Boston-Europe -connect will not be allowed. This has the effect of allowing multiple -US-EU links but attempting to limit these links to one server (ie: -Boston will not initiate its first Europe link if another server is -already linking Europe). This rule will also prefer to let Manhattan -handle the US-EU link by disallowing Boston-Europe links if a Europe -server is already linked to Manhattan. - -A example of the remaining function, directop(), is: - -connected(*eu.under*) || directop() - -If this line is used on Boston for the Paderborn CN pair, it will allow -connects to Paderborn only if another Europe server is not already -connected and there is not an oper on Boston. If this rule is -overrideable (ie: is applied only to autoconnects as described below), -then it will disallow Boston autoconnects to Paderborn while a Boston -oper is online, but allow oper-initiated connects to Paderborn under any -circumstance. This directop() function could be used to invoke less -prefered routes only when an oper is not present to handle routing, or -conversly to allow use of less preferable routes only when an oper is -present to monitor their performance. - -ircd.conf entries ------------------ - -A rule is listed in the ircd.conf file using a D or d line (which can -be thought of as a "disallow" line). D lines will apply to all oper -and server originated connects, while d lines will apply only to -autoconnects (ie: they are overrideable by opers). The formats are: - -D:targetmask::rule -d:targetmask::rule - -Remember that newlines are not allowed in conf lines. Two examples -(from above) are: - -D:*eu.under*::connected(*eu.under*) -d:*eu.under*::connected(*eu.under*) || directop() - -Connects originating from other servers will be checked against and -matching D lines, while matching d lines will be ignored as it will not -be clear whether or not the connection attempt is oper initiated. - -Checking and viewing rules --------------------------- - -The chkconf program that comes with the servers has been modified to -also check your connect rules. If running in debug mode, parsing errors -will show up at debug level 8. To view rules online, "/stats d" can be -used to see all rules and "/stats D" can be used to view those rules -which affect oper initiated connects and accepts. - -Processing and storage ----------------------- - -The rules are parsed when the conf file is read and transformed into a -more efficiently computed form, then all applicable rules are -evaluated each time a connect command is given or an autoconnect is -due. If more than one applicable rule is given, only one need -evaluate to true for the connect to be allowed (ie: the rules are ored -together). Note that conditions that exist when the connect is -initiated might differ from conditions when the link is established. diff --git a/doc/readme.crules.md b/doc/readme.crules.md new file mode 100644 index 00000000..708c1894 --- /dev/null +++ b/doc/readme.crules.md @@ -0,0 +1,128 @@ +# Connection rules (CRULEs) + +Based on "SmartRoute — Rule based connects" by Tony Vencill (1994); +updated for the current configuration format. The implementation is +in `ircd/crule.c`. + +Rule based connects allow an admin to specify under what conditions a +connect should not be allowed. If no rules are specified for a given +Connect block, the connection is allowed under any condition. + +A rule may consist of any legal combination of the following functions +and operators. + +## Functions + +| Function | True if... | +|----------|------------| +| `connected(targetmask)` | a server other than that processing the rule is connected that matches the target mask | +| `directcon(targetmask)` | a server other than that processing the rule is directly connected that matches the target mask | +| `via(viamask, targetmask)` | a server other than that processing the rule matches the target mask and is connected via a directly connected server that matches the via mask | +| `directop()` | an oper is directly connected | + +## Operators + +| Operator | Meaning | +|----------|---------| +| `!arg` | true if the argument is false | +| `arg1 && arg2` | true if both arguments are true | +| `arg1 \|\| arg2` | true if either argument (or both) is true | + +Parentheses `()` are allowed for grouping. Without parentheses, `&&` +takes precedence over `||`, `!` takes precedence over both, and +evaluation is left to right. White space in a rule is ignored. +Invalid characters in a rule lead to the rule being ignored. + +## Examples + +A simple example of a connect rule might be: + +``` +connected(*eu.under*) +``` + +This might be used in a US Undernet server for a Europe Connect block +to ensure that a second Europe link is not allowed if one US-EU link +already exists. (On the Undernet, US server names are +city.state.us.undernet.org and Europe server names are +city.country.eu.undernet.org.) + +A more interesting example: + +``` +connected(*eu.under*) && ( !directcon(*eu.under*) || via(manhat*, *eu.under*) ) +``` + +Imagine the Boston Undernet server uses this rule for its Europe +Connect blocks. This says that a Boston-Europe connect is disallowed +whenever a Europe server is already connected, unless Boston is itself +directly connected to a Europe server and Manhattan is not the one +carrying it. The effect is to allow multiple US-EU links while +attempting to limit them to one server: Boston will not initiate its +first Europe link if another server already links Europe, and prefers +to let Manhattan handle the US-EU link. + +An example using `directop()`: + +``` +connected(*eu.under*) || directop() +``` + +If this rule is used on Boston for the Paderborn Connect block, it +disallows connects to Paderborn while no other Europe server is +connected and no oper is online on Boston. If the rule is +overrideable (i.e. applies only to autoconnects, see below), it +disallows Boston *auto*connects to Paderborn while a Boston oper is +online, but allows oper-initiated connects to Paderborn under any +circumstance. `directop()` can be used to invoke less preferred +routes only when an oper is not present to handle routing, or +conversely to allow use of less preferable routes only when an oper is +present to monitor their performance. + +## Configuration + +Rules are configured with CRULE blocks in `ircd.conf` (see +`doc/example.conf`): + +``` +CRULE +{ + server = "servermask"; + rule = "connectrule"; + # Setting all to yes makes the rule always apply. + # Otherwise it applies only to autoconnects. + all = yes; +}; +``` + +A block with `all = yes` applies to all oper- and server-originated +connects as well as autoconnects; without it, the rule applies only to +autoconnects and can therefore be overridden by an oper-initiated +connect. If more than one server mask is present in a single CRULE +block, the rule applies to all the matching servers. + +Connects originating from other servers are checked against matching +`all = yes` rules only; autoconnect-only rules are ignored for them, +as it is not clear whether the connection attempt was oper initiated. + +(Historical note: in the old flat configuration format these were the +`D:targetmask::rule` and `d:targetmask::rule` lines; `all = yes` +corresponds to the uppercase D form.) + +## Viewing rules + +To view rules online, `/stats d` (or `/stats maskrules`) shows all +rules, and `/stats D` (or `/stats crules`) shows only those rules +which also affect oper- and server-initiated connects. Both are +subject to the `HIS_STATS_d` feature. + +## Processing and storage + +The rules are parsed when the configuration file is read and +transformed into a more efficiently computed form; all applicable +rules are then evaluated each time a connect command is given or an +autoconnect is due. If more than one applicable rule is given, only +one need evaluate to true for the connect to be allowed (i.e. the +rules are OR'ed together). Note that conditions that exist when the +connect is initiated might differ from conditions when the link is +established. diff --git a/doc/readme.cvs b/doc/readme.cvs deleted file mode 100644 index ddc14d59..00000000 --- a/doc/readme.cvs +++ /dev/null @@ -1,42 +0,0 @@ -Notes on checking out from the Undernet CVS archive. - -The main trunk of the tree (HEAD) will be used for development only. -When the maintainers believe the code is stable enough to prepare for -a release, they will make a branch for that release series. - -Each branch will have a base name, which is the name of the release -series where dots are replaced with underscores. The branch name will -be the base name with the suffix "_branch". Once an official release -is made, each release branch will have one or more fixed tags and one -moving tag. The fixed tags will indicate specific patchlevels, and -have the base name with a suffix giving the zero-based patchlevel. -The moving tag's name will be the base name, and will always point to -the same state as some fixed tag on the branch. - -This allows developers to easily track the most recent version of any -branch (by checking out using the branch's name), and allows server -admins to easily track the most recent release on the branch (by -checking out using the branch's base name). - -For example, for the ircu2.10.12 release series, the branch's base -name is u2_10_12. The branch's name is u2_10_12_branch. The first -release (ircu2.10.12) would be permanently tagged as u2_10_12_0, and -until an update is released, it would also have the tag u2_10_12. -When the first update is released, it would be permanently tagged as -u2_10_12_01, and the tag u2_10_12 would be changed to point to it. - -If the current stable series is 2.10.12, server admins should check -out the code using the command: - cvs -d :pserver:anonymous@cvs.undernet.org:/cvsroot/undernet-ircu co -r u2_10_12 -P ircu2.10 -Admins may only run unreleased code on Undernet with coder-com -approval. The command above will retrieve the most recent release. - -Developers should check out the release branch using the command: - cvs -d :pserver:anonymous@cvs.undernet.org:/cvsroot/undernet-ircu co -r u2_10_12_branch -P ircu2.10 - -http://sourceforge.net/cvs/?group_id=63470 gives more information on -using CVS to access the ircu code; http://www.nongnu.org/cvs/ gives -more information on using CVS in general. - -NOTE: Release before ircu2.10.12 used a different branching scheme. -Older revisions of this readme.cvs explain that system. diff --git a/doc/readme.features b/doc/readme.features deleted file mode 100644 index c7512ed8..00000000 --- a/doc/readme.features +++ /dev/null @@ -1,1052 +0,0 @@ -Many of the old compile-time options are now configured through the -server configuration file, ircd.conf. This file is intended to -document each of these features. Logging, although also configured -through the use of Feature entries, is documented in doc/readme.log. NOTE -THAT THESE NAMES ARE CASE SENSITIVE! Values are not case sensitive -unless stated otherwise in the documentation for that feature. - -DOMAINNAME - * Type: string - * Default: picked by ./configure from /etc/resolv.conf - -This option allows you to specify what you consider to be "local." It -is only used for statistics. When you issue the IRC command /STATS w, -the server will respond with statistics of how many clients have been -connecting to your server in the last minute, hour and day. It will -give these statistics for all connections (including the servers), all -clients (from anywhere) and also for clients whose hostname ends on -the domain you specify here. So if you are an ISP and you want to -know what the client load from your own domain is, specify that domain -here. If you are unsure what to do, then it isn't really important -what you give here, just don't give an empty string. A good guess is -the last two parts of your own hostname (i.e., if your hostname is -foo.bar.nowhere.org, specify "nowhere.org"). Note that the string you -give should NOT start with a "." and you should not use quotes. - -RELIABLE_CLOCK - * Type: boolean - * Default: FALSE - -You should really ONLY specify "TRUE" here when your system clock is -stable and accurate at all times (within a few seconds). If you are -running ntpdate on a regular basis, or an equivalent like xntpd, to -keep your system clock synchronized over the network, then you might -have an accurate clock. However, this is not guaranteed; for example, -it is known that xntpd gives unstable results on Linux in some cases. -Note that an unstable clock is worse then an clock that has a constant -offset, because the servers attempt to correct for a constant offset, -but do not correct jumps of your system clock! In general you SHOULD -be running ntpdate or equivalent AND make sure it works when you run a -production server on Undernet. Otherwise leave your clock alone and -specify "FALSE" here. If unsure specify "FALSE"! - -BUFFERPOOL - * Type: integer - * Default: 27000000 - -This specifies the maximum amount of RAM that your server will -allocate for buffering sendQs. Small leafs can use a value as little -as 1000000, while large HUBs need to specify a value as high as -20000000. If you run out of memory, clients and/or servers are -dropped with the error "Buffer allocation error"; then you will have -to increase this number (and install more RAM if appropriate). If you -want a more educated guess for this value then realize that any value -is good if you _really_ would rather drop servers and clients than -allocate more memory; this will be the case when there is the danger -you may run out of memory for other allocations. Even if you run the -daemon on a dedicated machine, specifying all of the RAM you have is a -bad thing, because running out of memory is a lot worse than dropping -clients in a controlled way; if possible you should have memory left -for all the internal structures (channels, clients, ban lists, receive -buffers) at all times. On average, clients seem to use 150 bytes of -sendQ, but at peak moments this can easily increase to 2032 bytes per -client (sendQs are allocated in chunks of 2032 bytes). The maximum -possible amount that can be allocated for sendQs is the number of -connected clients times whatever you specified as the maximum sendQ in -your Class blocks in the ircd.conf file. That value will likely be larger -then the amount of RAM you have. The educated guess I talked about -earlier would be "number of clients" times * 2048 bytes + "size of -net.burst" * n, where "n" is 1 for leafs and up to 5 for HUBs. The -"size of net.burst" is about 125 bytes per online client (on the whole -network). For large HUBs with 4000 clients on a network with 30,000 -users, this results in 27 Mb. Leafs could use 12 Mb. Of course you -can use less when you have less than 4000 local clients. This value -is in bytes. - -HAS_FERGUSON_FLUSHER - * Type: boolean - * Default: FALSE - -If you have a server with a lot of resources available, this option -will cause the server to attempt to flush its internal buffers before -dropping clients during a net break. Don't define this if you don't -know for certain; if you're not careful this can end up rebooting -FreeBSD boxes. For more information, refer to freebsd.txt, also in -this directory. - -CLIENT_FLOOD - * Type: integer - * Default: 1024 - -Currently, everything that a client sends to a server is read by the -server and stored in a buffer (the clients receive queue). The server -will process messages from this queue one by one (running over all -clients each time). When a client sends new messages faster they get -processed, and the flood-accounted size of its receive buffer reaches -this value, the client is dropped with the error "Excess flood." Flood -accounting counts the RFC1459 message body only (through BUFSIZE); -leading IRCv3 client-tag prefixes are excluded so tagged and untagged -lines consume the same flood budget. A reasonable value is 1024 bytes. -Class maxflood overrides this per class; setting maxflood above -CLIENT_FLOOD also exempts that class from input throttling. - -CLIENT_TAG_FLOOD - * Type: integer - * Default: 8192 - -Separate recvQ ceiling for IRCv3 message-tag prefixes (`@…` through the -separating space). Independent of CLIENT_FLOOD so short bodies (e.g. -TAGMSG) cannot hide tag stuffing. Exceeding this limit disconnects the -client with the same "Excess flood" error. Feature-only — there is no -per-class override. A value of 0 disables the tag ceiling. - -SERVER_PORT - * Type: integer - * Default: 4400 - -When an IRC operator attempts a connect to another server, he or she -may not know which port the connect should go to. In this server -version, that operator may use the special port 0, in which case the -server will take the port from the Connect block. If no port is -specified in the Connect block, however, the port specified by this -option will be used instead. - -NODEFAULTMOTD - * Type: boolean - * Default: TRUE - -Every time a client connects to your server, the full Message of the -Day (as specified by the Motd blocks or by the file specified by the MPATH -option) is sent to the client. The server sends the Message of the -Day even though many clients permit the user to ignore it. Many users -never read the message of the day anyway, making it a huge waste of -bandwidth. If you specify "TRUE" here, then the server won't send the -MOTD to the client by default; instead, it will only tell the client -when the MOTD was last changed, and give instructions on how to obtain -it by typing /MOTD. - -MOTD_BANNER - * Type: string - * Default: NULL - -If you enable NODEFAULTMOTD, this specifies a one-line banner to be sent -to the client in addition to the instructions mentioned above. - -PROVIDER - * Type: string - * Default: NULL - -This string as added to the 001 numeric prefixed with "via" before the nick. -It's used for providing promotional space to providers as per CFV-202 - -KILL_IPMISMATCH - * Type: boolean - - * Default: FALSE - -When a client connects to your server, the IP address of the client is -reverse-resolved to obtain a hostname. Then that hostname is resolved -to an IP address and compared with the IP address of the client. If -they don't match, the client will appear with the IP address instead -of the hostname, unless KILL_IPMISMATCH is "TRUE," in which case the -client is simply disconnected. - -IDLE_FROM_MSG - * Type: boolean - * Default: TRUE - -The IRC command WHOIS gives an idle time for clients. If you want -this idle time to be set to zero only when the client sends a PRIVMSG, -then you should specify "TRUE" here. If you specify "FALSE," then the -idle time will be nullified on all messages except the server -PING/PONG. - -HUB - * Type: boolean - * Default: FALSE - -All servers of an IRC "network" are connected in a "tree" (no loops). -Servers that are only connected to one other server (called the -"uplink") are called "leafs"; servers that are connected to more than -one other server are called HUBs. If you specify "FALSE" here then -your server will prevent itself from accidentally connecting to two -servers at once, thus keeping servers in poor network locations from -routing traffic. Note that on Undernet, all newly linked servers are -linked as leafs during their test phase, and should specify "FALSE" -here. - -WALLOPS_OPER_ONLY - * Type: boolean - * Default: FALSE - -Setting this option removes the ability for clients that are not IRC -operators to see wallops messages. - -NODNS - * Type: boolean - * Default: FALSE - -If you are playing with the server off-line, and no DNS is available, -then long delays occur before the server starts up because it tries to -resolve the name given in the General block (which usually isn't given -in /etc/hosts) and for each connecting client. If you specify "TRUE" -here, then a DNS lookup will be done only for the real hostname, and -the server will not try to resolve clients that connect to -"localhost." Note that other DNS lookups are still done for outbound -connections. - -RANDOM_SEED - * Type: string - * Default: none - -When a client connects, the server sends the client a "cookie," -consisting of a random number. The client must return the cookie to -the server verbatim. This is done to prevent IP spoofing. The cookie -is generated by a pseudorandom number generator included in ircd. -This generator must be seeded with a phrase that is kept secret, to -ensure that the numbers it generates are not easily guessed. The -value given to RANDOM_SEED may be a string of any length. It should -not contain any characters that are considered special by the -configuration file system, such as ":" or "#"; the string should be at -least 8 characters long, but longer strings are better. The -RANDOM_SEED may not be retrieved online. - -DEFAULT_LIST_PARAM - * Type: string - * Default: none - -The LIST command takes a single optional argument. If given, that -argument is either a channel or a filter. If that argument is not -given, then by default, /LIST will list all channels on the network. -Needless to say, this can generate a large amount of data on large -networks with many channels, as well as chewing up a lot of CPU time. -Server administrators can therefore set a default filter to be applied -to the channel list if the optional argument to LIST is omitted. - -NICKNAMEHISTORYLENGTH - * Type: integer - * Default: 800 - -This value specifies the length of the nick name history list, which -is used for /WHOWAS and some nickname chasing in /KILL and /KICK. It -uses about 300 to 400 bytes per entry. Note that at a net break, so -many client disappear that the whole "whowas" list is refreshed a few -times (unless you make it rather large). A reasonable value is "total -number of clients" / 25. - -HOST_HIDING - * Type: boolean - * Default: TRUE - -This selects whether local users can set umode +x, thus allowing them -to hide their hostname if they have also registered with a channel -service (i.e. they have the ACCOUNT flag set). - -HIDDEN_HOST - * Type: string - * Default: users.undernet.org - -This selects the suffix for the hidden hostmask (see HOST_HIDING). - -HIDDEN_IP - * Type: string - * Default: 127.0.0.1 - -This selects a fake IP to be shown on /USERIP and /WHO %i when the -target has a hidden host (see HOST_HIDING). - -TRUST_USERNAME - * Type: boolean - * Default: TRUE - -When enabled, other users see a fully hidden client's username without -a leading tilde (~) in WHOIS, USERHOST, USERIP, NAMES (UHNAMES), and -similar user-facing output. Both umode +x and a registered account -are required (see HOST_HIDING). Internal username records and server -propagation still use the real tilded username. Channel bans (and -silence) match those two complete identities only (~user@realhost and -user@account.hiddenhost), not mixed forms such as user@realhost. -G-lines continue to match only the real tilded username and real host. - -CONNEXIT_NOTICES - * Type: boolean - * Default: FALSE - -This feature controls the generation of server notices when a user -connects to or disconnects from the server. Enabling this feature may -have a performance impact. - -KILLCHASETIMELIMIT - * Type: integer - * Default: 30 - -If a user changes his or her nickname just before an operator issues a -/KILL, the /KILL will be changed to follow the user the operator -intended to get. This option specifies the time limit, in seconds, -for this nickname change; if the user changed his or her nickname more -than this many seconds ago, the /KILL will not be changed. Don't -change this unless you really need to. - -MAXCHANNELSPERUSER - * Type: integer - * Default: 10 - -This is the maximum number of channels a user can be in at a time. -The "mandatory" value on Undernet is currently 10. Since it only -influences the local server when you decrease it, its up to you to -decide if you want to use a smaller value. Do not use a larger value -however, because it DOES cost more memory and bandwidth on all other -servers when you allow users to join more channels simultaneously. -One of the most important reasons to choose a smaller value is the -fact that the "GUI" clients tend to stay on every channel they join -(they aren't bothered by flooding in other channels). It DOES take -your bandwidth however to send all those messages for 10 different -channels to all your users. - -AVBANLEN - * Type: integer - * Default: 40 - -This is the expected average ban mask length. Leave it at 40. - -MAXBANS - * Type: integer - * Default: 100 - -This is the maximum number of bans a user may set on a given channel. - -MAXSILES - * Type: integer - * Default: 15 - -This is the maximum number of masks a user can silence at a time. The -silence command allows users to filter messages directed at them from -certain users or domains, at the source server. Increasing this -number allows users to use up more memory with inefficient use of the -command. If you're not sure, don't change this. - -HANGONGOODLINK - * Type: integer - * Default: 300 - -Often the net breaks for a short time and it is useful to try to -reestablish the same connection faster than CONNECTFREQUENCY would -allow, but to keep from trying again on a bad connection, we require -that the connection be open for a certain minimum time. The -recommended value is 300 seconds. - -HANGONRETRYDELAY - * Type: integer - * Default: 10 - -When attempting to quickly reestablish a connection to a good link, we -give the net a few seconds to calm down. This time must be long enough -for the other end to also notice that the connection is broken. The -recommended value is 10 seconds. - -CONNECTTIMEOUT - * Type: integer - * Default: 90 - -Number of seconds to wait for a client registration to complete. NOTE: -this must be at *LEAST* 10. When a client connects, it has -CONNECTTIMEOUT - 10 seconds for its host to respond to an ident lookup -query and for a DNS lookup to complete. It is recommended that you not -change this value, but if you do, consider the fact that users whose -clients do not support NOSPOOF will have to type /QUOTE PING before registration. - -PINGFREQUENCY - * Type: integer - * Default: 120 - -If the daemon doesn't receive anything from any of its links within -PINGFREQUENCY seconds, then the it will attempt to check for an active -link with a PING message. If no reply is received within -(PINGFREQUENCY * 2) seconds, then the connection will be closed. This -value may be overridden by a Class block in "ircd.conf" if the -connection's Client or Connect block in "ircd.conf" assigns a specific -class to the connection (recommended). - -CONNECTFREQUENCY - * Type: integer - * Default: 600 - -This is the default frequency that the server attempts to reconnect -with its uplink server if it is set to auto connect to it. Note that -this value is overridden by a Class block in ircd.conf if the Connect -entries in ircd.conf assign a specific class to the connection. - -DEFAULTMAXSENDQLENGTH - * Type: integer - * Default: 40000 - -This is the default value of the maximum sendQ length of connection -classes (see doc/example.conf for details on Class blocks). You will -generally override this value in your "ircd.conf" with a Class block. - -GLINEMAXUSERCOUNT - * Type: integer - * Default: 20 - -G-lines that affect too many users have to be set with a special -command, to prevent accidental G-lines of large blocks of users. This -feature sets that particular threshold. - -MPATH - * Type: string - * Default: "ircd.motd" - -MPATH is the filename (relative to DPATH) or the full path of the -"Message of the Day" file. The contents of this file will be sent to -every client that connects to the server, after registration. - -RPATH - * Type: string - * Default: "remote.motd" - -RPATH is the filename (relative to DPATH) or the full path of the -"Remote Message of the Day" file. The contents of this file will be -sent to every remote client that issues a /MOTD . -Only the first three lines are sent, so you might want to keep that in -mind while writing the file. - -PPATH - * Type: string - * Default: "ircd.pid" - -PPATH is the filename (relative to DPATH) or the full path of the -"PID" file. It is used for storing the server's process ID so that a -ps(1) isn't necessary. - -TOS_SERVER - * Type: integer - * Default: 0x08 - -This option is used to specify the type of service that will be -requested for connections to other servers. The value may be given as -a hexadecimal integer. - -TOS_CLIENT - * Type: integer - * Default: 0x08 - -This option is used to specify the type of service that will be -requested for connections to users. The value may be given as a -hexadecimal integer. - -POLLS_PER_LOOP - * Type: integer - * Default: 200 - -Some of the engines used by the event interface get a number of events -from the kernel at once. Since the number retrieved can impact -performance, it can be tuned by modifying this value. The engines -enforce a lower limit of 20. - -CONFIG_OPERCMDS - * Type: boolean - * Default: FALSE - -Since u2.10.11, several new oper-only features have been added that -involve changes to the server<->server protocol. This configuration -option provides a single switch to prevent the use of these features -until the entire network has been upgraded. It is not required that -all servers set this to "TRUE" in order for the features to be used, -as long as all servers are running u2.10.11 or above. - -STRICT_USERNAME - * Type: boolean - * Default: FALSE - -ircu checks the composition of usernames and reject usernames matching -certain rules. Enabling this feature will reject users with usernames -matching any of the following additional criterias: - - If mixed case, first must be capital, but no more than three; - but if three capitals, they must all be leading. - - If two different groups of digits, one must be either at the - start or end. - - No more than two groups of digits. - - Final character must not be punctuation. - -HIS_MAP - * Type: boolean - * Default: TRUE - -As per UnderNet CFV-165, this removes /MAP from users. - -HIS_SNOTICES - * Type: boolean - * Default: TRUE - -As per UnderNet CFV-165, this removes server notices from users. - -HIS_SNOTICES_OPER_ONLY - * Type: boolean - * Default: TRUE - -As per UnderNet CFV-165, this removes server notices from users. - -HIS_DEBUG_OPER_ONLY - * Type: boolean - * Default: TRUE - -As per UnderNet CFV-165, this removes server wallops from users. - -HIS_WALLOPS - * Type: boolean - * Default: TRUE - -As per UnderNet CFV-165, this removes operator wallops from users. - -HIS_LINKS - * Type: boolean - * Default: TRUE - -As per UnderNet CFV-165, this removes /LINKS from users. - -HIS_TRACE - * Type: boolean - * Default: TRUE - -As per UnderNet CFV-165, this removes /TRACE from users. - -HIS_STATS_a - * Type: boolean - * Default: TRUE - -As per UnderNet CFV-165, this removes /STATS a from users. - -HIS_STATS_c - * Type: boolean - * Default: TRUE - -As per UnderNet CFV-165, this removes /STATS c from users. - -HIS_STATS_d - * Type: boolean - * Default: TRUE - -As per UnderNet CFV-165, this removes /STATS d from users. - -HIS_STATS_e - * Type: boolean - * Default: TRUE - -As per UnderNet CFV-165, this removes /STATS e from users. - -HIS_STATS_f - * Type: boolean - * Default: TRUE - -As per UnderNet CFV-165, this removes /STATS f from users. - -HIS_STATS_g - * Type: boolean - * Default: TRUE - -As per UnderNet CFV-165, this removes /STATS g from users. - -HIS_STATS_i - * Type: boolean - * Default: TRUE - -As per UnderNet CFV-165, this removes /STATS i from users. - -HIS_STATS_j - * Type: boolean - * Default: TRUE - -As per UnderNet CFV-165, this removes /STATS j from users. - -HIS_STATS_J - * Type: boolean - * Default: TRUE - -As per UnderNet CFV-165, this removes /STATS J from users. - -HIS_STATS_k - * Type: boolean - * Default: TRUE - -As per UnderNet CFV-165, this removes /STATS k from users. - -HIS_STATS_l - * Type: boolean - * Default: TRUE - -As per UnderNet CFV-165, this removes /STATS l from users. - -HIS_STATS_L - * Type: boolean - * Default: TRUE - -As per UnderNet CFV-165, this removes /STATS L from users. - -HIS_STATS_M - * Type: boolean - * Default: TRUE - -As per UnderNet CFV-165, this removes /STATS M from users. - -HIS_STATS_m - * Type: boolean - * Default: TRUE - -As per UnderNet CFV-165, this removes /STATS m from users. - -HIS_STATS_o - * Type: boolean - * Default: TRUE - -As per UnderNet CFV-165, this removes /STATS o from users. - -HIS_STATS_p - * Type: boolean - * Default: TRUE - -As per UnderNet CFV-165, this removes /STATS p from users. - -HIS_STATS_q - * Type: boolean - * Default: TRUE - -As per UnderNet CFV-165, this removes /STATS q from users. - -HIS_STATS_r - * Type: boolean - * Default: TRUE - -As per UnderNet CFV-165, this removes /STATS r from users. - -HIS_STATS_R - * Type: boolean - * Default: TRUE - -As per UnderNet CFV-165, this removes /STATS R from users. - -HIS_STATS_t - * Type: boolean - * Default: TRUE - -As per UnderNet CFV-165, this removes /STATS t from users. - -HIS_STATS_T - * Type: boolean - * Default: TRUE - -As per UnderNet CFV-165, this removes /STATS T from users. - -HIS_STATS_u - * Type: boolean - * Default: FALSE - -As per UnderNet CFV-165, this allows users to perform /STATS u. - -HIS_STATS_U - * Type: boolean - * Default: TRUE - -As per UnderNet CFV-165, this removes /STATS U from users. - -HIS_STATS_v - * Type: boolean - * Default: TRUE - -As per UnderNet CFV-165, this removes /STATS v from users. - -HIS_STATS_w - * Type: boolean - * Default: FALSE - -As per UnderNet CFV-165, this allows users to perform /STATS w. - -HIS_STATS_W - * Type: boolean - * Default: TRUE - -As per UnderNet CFV-165, this removes /STATS W from users. - -HIS_STATS_x - * Type: boolean - * Default: TRUE - -As per UnderNet CFV-165, this removes /STATS x from users. - -HIS_STATS_y - * Type: boolean - * Default: TRUE - -As per UnderNet CFV-165, this removes /STATS y from users. - -HIS_STATS_z - * Type: boolean - * Default: TRUE - -As per UnderNet CFV-165, this removes /STATS z from users. - -HIS_STATS_IAUTH - * Type: boolean - * Default: TRUE - -As per UnderNet CFV-165, this disables /STATS IAUTH and -/STATS IAUTHCONF from users. - -HIS_WEBIRC - * Type: boolean - * Default: TRUE - -As per UnderNet CFV-165, this disables display of WebIRC status in -/WHOIS replies (unless the client is asking about itself) and the -^ prefix for WebIRC usernames. - -HIS_WHOIS_SERVERNAME - * Type: boolean - * Default: TRUE - -As per UnderNet CFV-165, this removes server names in replies to /WHOIS. - -HIS_WHOIS_IDLETIME - * Type: boolean - * Default: TRUE - -As per UnderNet CFV-165, this removes idle time in replies to /WHOIS. - -HIS_WHO_SERVERNAME - * Type: boolean - * Default: TRUE - -As per UnderNet CFV-165, this removes server names in replies to /WHO. - -HIS_WHO_HOPCOUNT - * Type: boolean - * Default: TRUE - -As per UnderNet CFV-165, this replaces hopcount to a static 3 in -replies to /WHO. - -HIS_MODEWHO - * Type: boolean - * Default: TRUE - -As per UnderNet CFV-165, this doesn't show which server performed a channel -mode change. - -HIS_BANWHO - * Type: boolean - * Default: TRUE - -As per UnderNet CFV-165, this doesn't show which server set a ban. - -HIS_KILLWHO - * Type: boolean - * Default: TRUE - -As per UnderNet CFV-165, this doesn't show which server or oper performed a -kill. - -HIS_REWRITE - * Type: boolean - * Default: TRUE - -As per UnderNet CFV-165, this remaps remote numerics to come from the local -server. - -HIS_REMOTE - * Type: boolean - * Default: TRUE - -As per UnderNet CFV-165, this disallows remote queries. (*sob!*) - -HIS_NETSPLIT - * Type: boolean - * Default: TRUE - -As per UnderNet CFV-165, this removes server names in net break sign-offs. - -HIS_WHOIS_LOCALCHAN - * Type: boolean - * Default: TRUE - -As per UnderNet CFV-165, this removes local channels in replies to /WHOIS. - -HIS_SERVERNAME - * Type: string - * Default: "*.undernet.org" - -As per UnderNet CFV-165, this is the "name" of the server shown to users on a -/WHOIS of another user. - -HIS_SERVERINFO - * Type: string - * Default: "The Undernet Underworld" - -As per UnderNet CFV-165, this is the "info" of the server shown to users on a -/WHOIS of another user. - -HIS_URLSERVERS - * Type: string - * Default: "http://www.undernet.org/servers.php" - -As per UnderNet CFV-165, this is the URL shown to users when they do a /MAP or -/LINKS. - -NETWORK - * Type: string - * Default: "UnderNet" - -This defines the network name as reported in the 005 "supported features" -numeric, and as used by the "Failed to deliver" message. - -URL_CLIENTS - * Type: string - * Default: "ftp://ftp.undernet.org/pub/irc/clients" - -This defines a URL that users may visit to find compatible IRC clients. - -URLREG - * Type: string - * Default: "http://cservice.undernet.org/live/" - -This defines a URL that is used in server response 477 (ERR_NEEDREGGEDNICK) to -let users know which website they must visit to obtain a proper account for -authentication. - -NICKLEN - * Type: integer - * Default: 12 - -This is the allowed length of the nickname length. It may not be -larger than the NICKLEN #define, and should usually be the same -length. The real purpose of this feature is to permit easy increases -in nickname length for a network. - -IRCD_RES_RETRIES - * Type: integer - * Default: 2 - -This is the number of attempts the irc daemon's resolver will have at -trying to solicit a response from the DNS server. - -IRCD_RES_TIMEOUT - * Type: integer - * Default: 4 - -When a DNS query is sent, the irc daemon's resolver will wait this many -seconds for a reply. After this timeout has expired, it will retry again, -for as many retries as IRCD_RES_RETRIES allows. This can be cut short by -AUTH_TIMEOUT expiring. -NOTE: Has no effect when using the adns resolver. - -DNS_TCP_MAXCONN - * Type: integer - * Default: 256 - -Maximum number of concurrent DNS-over-TCP connections used when a UDP -response is truncated (TC=1). This bounds file-descriptor and nameserver -load if many clients trigger TCP retries. Excess TC=1 lookups fail that -client's hostname check instead of opening another TCP session. Set to 0 -for no limit. - -AUTH_TIMEOUT - * Type: integer - * Default: 9 - -This is the maximum number of seconds to wait for the ident lookup and -the DNS query to succeed. On older (pre 2.10.11.06) servers this was -hard coded to 60 seconds. - -WEBSOCKET_KEEPALIVE - * Type: integer - * Default: 0 (disabled) - -If greater than zero, the server sends an RFC 6455 WebSocket Ping frame -to registered clients on WebSocket listener connections at this interval -(in seconds). This is for transport / idle TCP keepalive only; it does -not replace IRC PING/PONG (see PINGFREQUENCY and related settings). - -WEBSOCKET_ALLOWED_ORIGINS - * Type: string - * Default: empty (all origins allowed) - -If set, WebSocket handshakes are accepted only when their HTTP Origin -header exactly matches one of the space- or comma-separated entries in -this list (case-insensitive); a handshake with a non-matching or missing -Origin is rejected. When empty (the default), the Origin header is not -checked and any origin may connect, which is the traditional behavior. - -IPCHECK_CLONE_LIMIT - * Type: integer - * Default: 4 - -The number of times you are allowed to connect within IPCHECK_CLONE_PERIOD -seconds before you are considered abusing the server and throttled. - -IPCHECK_CLONE_PERIOD - * Type: integer - * Default: 40 - -The number of seconds you are allowed to connect IPCHECK_CLONE_LIMIT times -within before you are considered abusing the server and throttled. -For instance if you set IPCHECK_CLONE_LIMIT to 1, and IPCHECK_CLONE_PERIOD -to 10, then a user is only allowed to connect once in 10s, if they connect -again within 10s, then they are considered to be connecting too fast and -they are throttled. - -IPCHECK_48_CLONE_LIMIT - * Type: integer - * Default: 50 - -This is a limit that works like IPCHECK_CLONE_LIMIT, but for all -clients connecting from a given IPv6 /48 block. - -IPCHECK_48_CLONE_PERIOD - * Type: integer - * Default: 10 - -This is a timer that works like IPCHECK_CLONE_PERIOD, but for all -clients connecting from a given IPv6 /48 block. The number of -connection attempts allowed in this period is given by the -IPCHECK_48_CLONE_LIMIT feature. - -IPCHECK_CLONE_DELAY - * Type: integer - * Default: 600 - -The number of seconds grace after restarting the server before the throttle -code kicks in. Even if a user connects repetitively during this period, -they will never get throttled. This is so after a restart users on a -multiuser box can all connect to a server simultaniously without being -considered an attack. - -SOCKSENDBUF - * Type: integer - * Default: 61440 - -The send window size used for connections to other servers. - -SOCKRECVBUF - * Type: integer - * Default: 61440 - -The receive window size used for connections to other servers. - -ANNOUNCE_INVITES - * Type: boolean - * Default: FALSE - -If set, send RPL_ISSUEDINVITE (345) to a channel's operators to -announce when someone is invited to the channel. - -LOCAL_CHANNELS - * Type: boolean - * Default: TRUE - -If set, allow users to create local channels. - -TOPIC_BURST - * Type: boolean - * Default: TRUE - -Send during burst the current topic, nick of person who set the topic and -topic timestamp. - -AWAY_BURST - * Type: boolean - * Default: TRUE - -Send the away message for clients flagged as away during burst. - -CHANNELLEN - * Type: integer - * Default: 200 - -This is the allowed length of locally created channels. It may not be -larger than the CHANNELLEN #define. Like the NICKLEN feature, this is -intended to ease changes in channel name length across a network. - -OPLEVELS - * Type: boolean - * Default: FALSE - -This allows local users to set the +A and +U modes (admin and user -passwords, respectively) on channels where they are marked as channel -managers. This feature must be disabled until all servers on the -network are able to interpret and handle these modes correctly. - -TLS_SYSTEMCA - * Type: boolean - * Default: TRUE - -When TRUE, TLS connections whose Port or Connect block does not set -"tls systemca" and does not set "tls cacertfile" or "tls cacertdir" -will load the operating system's trusted CA certificate store. Per-block -TLS trust settings are documented in doc/example.conf. - -NETWORK_FEATURES - * Type: boolean - * Default: TRUE - -When TRUE, this server emits non-backwards-compatible S2S extensions: -TLS certificate fingerprints on NICK/umode bursts, relay of remote -OPMODE +x toward a user's home server, relay of ACCOUNT updates for -users who are already authenticated (e.g. account flag changes), -IRCv3 message-tags prefixes on server links, and TAGMSG (TM) to -servers. Set FALSE while some peers still run older ircu that cannot -parse those fields, then turn it back on once the network is fully -upgraded. Peers on u2.10.12.19 and earlier protocol_violate on a -second ACCOUNT for an already-authed nick; u2.10.13.0 tolerates -same-name updates locally. Inbound extensions are still accepted when -this is FALSE (TAGMSG is delivered to local clients only). Federating -@time= specifically is controlled by NETWORK_TIME. - -NETWORK_TIME - * Type: boolean - * Default: TRUE - -When TRUE, this server invents and forwards @time= on P10 for -client-visible events (subject to NETWORK_FEATURES). When FALSE, time -is not sent on S2S; clients that negotiated server-time or message-tags -receive a stamp based on CurrentTime at local delivery instead of any -upstream time tag. - -TLS_CIPHERS - * Type: string - * Default: "" - -This specifies the default list of ciphers to use. This list is used -for outbound connections to servers with no "tls ciphers" directive in -their Connect blocks, and for inbound connections on TLS-only ports with -no "tls ciphers" directive in their Port blocks. - -This cipher list is interpreted by, and thus depends on, the TLS library -in use: - - - For all libraries, an empty string represents use of the library's - default cipher suites. - - For OpenSSL, it is parsed as "L1 L2" (two lists, separated by spaces) - where L1 is used for TLSv1.2 and below (with SSL_set_cipher_list()) - and L2 is used for TLSv1.3 (with SSL_set_ciphersuites()). - - For GnuTLS, it is parsed as a "priority string" by the function - gnutls_priority_init() and then applied to sessions. - - For OpenBSD's libtls, it is passed to tls_config_set_ciphers(). - -ZANNELS - * Type: boolean - * Default: FALSE - -This preserves empty channels with no admin password so that it is -impractical to become the channel manager by clearing out the channel. -It must be set to FALSE if there are both 2.10.11.x servers and -2.10.12.y servers on the network where y < 4. It should be set to -TRUE whenever the OPLEVELS features is TRUE. diff --git a/doc/readme.features.md b/doc/readme.features.md new file mode 100644 index 00000000..461389ff --- /dev/null +++ b/doc/readme.features.md @@ -0,0 +1,1216 @@ +# Feature settings + +Many of the old compile-time options are now configured through the server configuration file, `ircd.conf`. +This file is intended to document each of these features. +Logging, although also configured through the use of Feature entries, is documented in `doc/readme.log`. + +**NOTE: These names are case sensitive!** +Values are not case sensitive unless stated otherwise in the documentation for that feature. + +## DOMAINNAME + +* **Type:** string +* **Default:** picked by `./configure` from `/etc/resolv.conf` + +This option allows you to specify what you consider to be "local." +It is only used for statistics. +When you issue the IRC command `/STATS w`, the server will respond with statistics of how many clients have been connecting to your server in the last minute, hour and day. + +It will give these statistics for all connections (including the servers), all clients (from anywhere) and also for clients whose hostname ends on the domain you specify here. + +So if you are an ISP and you want to know what the client load from your own domain is, specify that domain here. + +If you are unsure what to do, then it isn't really important what you give here, just don't give an empty string. + +A good guess is the last two parts of your own hostname (i.e., if your hostname is foo.bar.nowhere.org, specify "nowhere.org"). + +Note that the string you give should NOT start with a "." and you should not use quotes. + +## RELIABLE_CLOCK + +* **Type:** boolean +* **Default:** `FALSE` + +You should really ONLY specify `TRUE` here when your system clock is stable and accurate at all times (within a few seconds). +If you are running ntpdate on a regular basis, or an equivalent like xntpd, to keep your system clock synchronized over the network, then you might have an accurate clock. + +However, this is not guaranteed; for example, it is known that xntpd gives unstable results on Linux in some cases. + +Note that an unstable clock is worse then an clock that has a constant offset, because the servers attempt to correct for a constant offset, but do not correct jumps of your system clock! + +In general you SHOULD be running ntpdate or equivalent AND make sure it works when you run a production server on Undernet. + +Otherwise leave your clock alone and specify `FALSE` here. + +If unsure specify `FALSE`! + +## BUFFERPOOL + +* **Type:** integer +* **Default:** 27000000 + +This specifies the maximum amount of RAM that your server will allocate for buffering sendQs. +Small leafs can use a value as little as 1000000, while large HUBs need to specify a value as high as 20000000. +If you run out of memory, clients and/or servers are dropped with the error "Buffer allocation error"; then you will have to increase this number (and install more RAM if appropriate). + +If you want a more educated guess for this value then realize that any value is good if you _really_ would rather drop servers and clients than allocate more memory; this will be the case when there is the danger you may run out of memory for other allocations. + +Even if you run the daemon on a dedicated machine, specifying all of the RAM you have is a bad thing, because running out of memory is a lot worse than dropping clients in a controlled way; if possible you should have memory left for all the internal structures (channels, clients, ban lists, receive buffers) at all times. + +On average, clients seem to use 150 bytes of sendQ, but at peak moments this can easily increase to 2032 bytes per client (sendQs are allocated in chunks of 2032 bytes). +The maximum possible amount that can be allocated for sendQs is the number of connected clients times whatever you specified as the maximum sendQ in your `Class` blocks in the `ircd.conf` file. +That value will likely be larger then the amount of RAM you have. + +The educated guess I talked about earlier would be "number of clients" times * 2048 bytes + "size of net.burst" * n, where "n" is 1 for leafs and up to 5 for HUBs. +The "size of net.burst" is about 125 bytes per online client (on the whole network). +For large HUBs with 4000 clients on a network with 30,000 users, this results in 27 Mb. + +Leafs could use 12 Mb. + +Of course you can use less when you have less than 4000 local clients. + +This value is in bytes. + +## HAS_FERGUSON_FLUSHER + +* **Type:** boolean +* **Default:** `FALSE` + +If you have a server with a lot of resources available, this option will cause the server to attempt to flush its internal buffers before dropping clients during a net break. + +Don't define this if you don't know for certain; if you're not careful this can end up rebooting FreeBSD boxes. + +For more information, refer to `freebsd.txt`, also in this directory. + +## CLIENT_FLOOD + +* **Type:** integer +* **Default:** 1024 + +Currently, everything that a client sends to a server is read by the server and stored in a buffer (the clients receive queue). +The server will process messages from this queue one by one (running over all clients each time). +When a client sends new messages faster they get processed, and the flood-accounted size of its receive buffer reaches this value, the client is dropped with the error "Excess flood." +Flood accounting counts the RFC1459 message body only (through `BUFSIZE`); leading IRCv3 client-tag prefixes are excluded so tagged and untagged lines consume the same flood budget. + +A reasonable value is 1024 bytes. +Class maxflood overrides this per class; setting maxflood above `CLIENT_FLOOD` also exempts that class from input throttling. + +## CLIENT_TAG_FLOOD + +* **Type:** integer +* **Default:** 8192 + +Separate recvQ ceiling for IRCv3 message-tag prefixes (`@…` through the separating space). +Independent of `CLIENT_FLOOD` so short bodies (e.g. `TAGMSG`) cannot hide tag stuffing. +Exceeding this limit disconnects the client with the same "Excess flood" error. +Feature-only — there is no per-class override. +A value of 0 disables the tag ceiling. + +## SERVER_PORT + +* **Type:** integer +* **Default:** 4400 + +When an IRC operator attempts a connect to another server, he or she may not know which port the connect should go to. +In this server version, that operator may use the special port 0, in which case the server will take the port from the Connect block. +If no port is specified in the Connect block, however, the port specified by this option will be used instead. + +## NODEFAULTMOTD + +* **Type:** boolean +* **Default:** `TRUE` + +Every time a client connects to your server, the full Message of the Day (as specified by the Motd blocks or by the file specified by the `MPATH` option) is sent to the client. +The server sends the Message of the Day even though many clients permit the user to ignore it. +Many users never read the message of the day anyway, making it a huge waste of bandwidth. + +If you specify `TRUE` here, then the server won't send the MOTD to the client by default; instead, it will only tell the client when the MOTD was last changed, and give instructions on how to obtain it by typing `/MOTD`. + +## MOTD_BANNER + +* **Type:** string +* **Default:** NULL + +If you enable `NODEFAULTMOTD`, this specifies a one-line banner to be sent to the client in addition to the instructions mentioned above. + +## PROVIDER + +* **Type:** string +* **Default:** NULL + +This string as added to the 001 numeric prefixed with "via" before the nick. +It's used for providing promotional space to providers as per CFV-202 + +## KILL_IPMISMATCH + +* **Type:** boolean +* **Default:** `FALSE` + +When a client connects to your server, the IP address of the client is reverse-resolved to obtain a hostname. +Then that hostname is resolved to an IP address and compared with the IP address of the client. +If they don't match, the client will appear with the IP address instead of the hostname, unless `KILL_IPMISMATCH` is `TRUE`, in which case the client is simply disconnected. + +## IDLE_FROM_MSG + +* **Type:** boolean +* **Default:** `TRUE` + +The IRC command `/WHOIS` gives an idle time for clients. +If you want this idle time to be set to zero only when the client sends a `PRIVMSG`, then you should specify `TRUE` here. +If you specify `FALSE`, then the idle time will be nullified on all messages except the server `PING`/`PONG`. + +## HUB + +* **Type:** boolean +* **Default:** `FALSE` + +All servers of an IRC "network" are connected in a "tree" (no loops). +Servers that are only connected to one other server (called the "uplink") are called "leafs"; servers that are connected to more than one other server are called HUBs. +If you specify `FALSE` here then your server will prevent itself from accidentally connecting to two servers at once, thus keeping servers in poor network locations from routing traffic. + +Note that on Undernet, all newly linked servers are linked as leafs during their test phase, and should specify `FALSE` here. + +## WALLOPS_OPER_ONLY + +* **Type:** boolean +* **Default:** `FALSE` + +Setting this option removes the ability for clients that are not IRC operators to see wallops messages. + +## NODNS + +* **Type:** boolean +* **Default:** `FALSE` + +If you are playing with the server off-line, and no DNS is available, then long delays occur before the server starts up because it tries to resolve the name given in the General block (which usually isn't given in `/etc/hosts`) and for each connecting client. +If you specify `TRUE` here, then a DNS lookup will be done only for the real hostname, and the server will not try to resolve clients that connect to "localhost." + +Note that other DNS lookups are still done for outbound connections. + +## RANDOM_SEED + +* **Type:** string +* **Default:** none + +When a client connects, the server sends the client a "cookie," consisting of a random number. +The client must return the cookie to the server verbatim. +This is done to prevent IP spoofing. + +The cookie is generated by a pseudorandom number generator included in ircd. +This generator must be seeded with a phrase that is kept secret, to ensure that the numbers it generates are not easily guessed. +The value given to `RANDOM_SEED` may be a string of any length. + +It should not contain any characters that are considered special by the configuration file system, such as ":" or "#"; the string should be at least 8 characters long, but longer strings are better. +The `RANDOM_SEED` may not be retrieved online. + +## DEFAULT_LIST_PARAM + +* **Type:** string +* **Default:** none + +The `LIST` command takes a single optional argument. +If given, that argument is either a channel or a filter. +If that argument is not given, then by default, `/LIST` will list all channels on the network. + +Needless to say, this can generate a large amount of data on large networks with many channels, as well as chewing up a lot of CPU time. + +Server administrators can therefore set a default filter to be applied to the channel list if the optional argument to `LIST` is omitted. + +## NICKNAMEHISTORYLENGTH + +* **Type:** integer +* **Default:** 800 + +This value specifies the length of the nick name history list, which is used for `/WHOWAS` and some nickname chasing in `/KILL` and `/KICK`. +It uses about 300 to 400 bytes per entry. + +Note that at a net break, so many client disappear that the whole "whowas" list is refreshed a few times (unless you make it rather large). + +A reasonable value is "total number of clients" / 25. + +## HOST_HIDING + +* **Type:** boolean +* **Default:** `TRUE` + +This selects whether local users can set umode `+x`, thus allowing them to hide their hostname if they have also registered with a channel service (i.e. they have the `ACCOUNT` flag set). + +## HIDDEN_HOST + +* **Type:** string +* **Default:** users.undernet.org + +This selects the suffix for the hidden hostmask (see `HOST_HIDING`). + +## HIDDEN_IP + +* **Type:** string +* **Default:** 127.0.0.1 + +This selects a fake IP to be shown on `/USERIP` and `/WHO %i` when the target has a hidden host (see `HOST_HIDING`). + +## TRUST_USERNAME + +* **Type:** boolean +* **Default:** `TRUE` + +When enabled, other users see a fully hidden client's username without a leading tilde (~) in `WHOIS`, `USERHOST`, `USERIP`, `NAMES` (UHNAMES), and similar user-facing output. +Both umode +x and a registered account are required (see `HOST_HIDING`). +Internal username records and server propagation still use the real tilded username. +Channel bans (and silence) match those two complete identities only (`~user@realhost` and `user@account.hiddenhost`), not mixed forms such as `user@realhost`. +G-lines continue to match only the real tilded username and real host. + +## CONNEXIT_NOTICES + +* **Type:** boolean +* **Default:** `FALSE` + +This feature controls the generation of server notices when a user connects to or disconnects from the server. +Enabling this feature may have a performance impact. + +## KILLCHASETIMELIMIT + +* **Type:** integer +* **Default:** 30 + +If a user changes his or her nickname just before an operator issues a `/KILL`, the `/KILL` will be changed to follow the user the operator intended to get. +This option specifies the time limit, in seconds, for this nickname change; if the user changed his or her nickname more than this many seconds ago, the `/KILL` will not be changed. + +Don't change this unless you really need to. + +## MAXCHANNELSPERUSER + +* **Type:** integer +* **Default:** 10 + +This is the maximum number of channels a user can be in at a time. +The "mandatory" value on Undernet is currently 10. +Since it only influences the local server when you decrease it, its up to you to decide if you want to use a smaller value. + +Do not use a larger value however, because it DOES cost more memory and bandwidth on all other servers when you allow users to join more channels simultaneously. +One of the most important reasons to choose a smaller value is the fact that the "GUI" clients tend to stay on every channel they join (they aren't bothered by flooding in other channels). +It DOES take your bandwidth however to send all those messages for 10 different channels to all your users. + +## AVBANLEN + +* **Type:** integer +* **Default:** 40 + +This is the expected average ban mask length. +Leave it at 40. + +## MAXBANS + +* **Type:** integer +* **Default:** 100 + +This is the maximum number of bans a user may set on a given channel. + +## MAXSILES + +* **Type:** integer +* **Default:** 15 + +This is the maximum number of masks a user can silence at a time. +The silence command allows users to filter messages directed at them from certain users or domains, at the source server. +Increasing this number allows users to use up more memory with inefficient use of the command. + +If you're not sure, don't change this. + +## HANGONGOODLINK + +* **Type:** integer +* **Default:** 300 + +Often the net breaks for a short time and it is useful to try to reestablish the same connection faster than `CONNECTFREQUENCY` would allow, but to keep from trying again on a bad connection, we require that the connection be open for a certain minimum time. +The recommended value is 300 seconds. + +## HANGONRETRYDELAY + +* **Type:** integer +* **Default:** 10 + +When attempting to quickly reestablish a connection to a good link, we give the net a few seconds to calm down. +This time must be long enough for the other end to also notice that the connection is broken. +The recommended value is 10 seconds. + +## CONNECTTIMEOUT + +* **Type:** integer +* **Default:** 90 + +Number of seconds to wait for a client registration to complete. +NOTE: this must be at *LEAST* 10. +When a client connects, it has `CONNECTTIMEOUT` - 10 seconds for its host to respond to an ident lookup query and for a DNS lookup to complete. + +It is recommended that you not change this value, but if you do, consider the fact that users whose clients do not support NOSPOOF will have to type `/QUOTE PING` before registration. + +## PINGFREQUENCY + +* **Type:** integer +* **Default:** 120 + +If the daemon doesn't receive anything from any of its links within `PINGFREQUENCY` seconds, then the it will attempt to check for an active link with a `PING` message. +If no reply is received within (`PINGFREQUENCY` * 2) seconds, then the connection will be closed. +This value may be overridden by a Class block in "`ircd.conf`" if the connection's Client or Connect block in "`ircd.conf`" assigns a specific class to the connection (recommended). + +## CONNECTFREQUENCY + +* **Type:** integer +* **Default:** 600 + +This is the default frequency that the server attempts to reconnect with its uplink server if it is set to auto connect to it. + +Note that this value is overridden by a Class block in `ircd.conf` if the Connect entries in `ircd.conf` assign a specific class to the connection. + +## DEFAULTMAXSENDQLENGTH + +* **Type:** integer +* **Default:** 40000 + +This is the default value of the maximum sendQ length of connection classes (see `doc/example.conf` for details on `Class` blocks). +You will generally override this value in your "`ircd.conf`" with a Class block. + +## GLINEMAXUSERCOUNT + +* **Type:** integer +* **Default:** 20 + +G-lines that affect too many users have to be set with a special command, to prevent accidental G-lines of large blocks of users. +This feature sets that particular threshold. + +## MPATH + +* **Type:** string +* **Default:** "`ircd.motd`" + +`MPATH` is the filename (relative to `DPATH`) or the full path of the "Message of the Day" file. +The contents of this file will be sent to every client that connects to the server, after registration. + +## RPATH + +* **Type:** string +* **Default:** "`remote.motd`" + +`RPATH` is the filename (relative to `DPATH`) or the full path of the "Remote Message of the Day" file. +The contents of this file will be sent to every remote client that issues a `/MOTD` . +Only the first three lines are sent, so you might want to keep that in mind while writing the file. + +## PPATH + +* **Type:** string +* **Default:** "`ircd.pid`" + +`PPATH` is the filename (relative to `DPATH`) or the full path of the "PID" file. +It is used for storing the server's process ID so that a ps(1) isn't necessary. + +## TOS_SERVER + +* **Type:** integer +* **Default:** 0x08 + +This option is used to specify the type of service that will be requested for connections to other servers. +The value may be given as a hexadecimal integer. + +## TOS_CLIENT + +* **Type:** integer +* **Default:** 0x08 + +This option is used to specify the type of service that will be requested for connections to users. +The value may be given as a hexadecimal integer. + +## POLLS_PER_LOOP + +* **Type:** integer +* **Default:** 200 + +Some of the engines used by the event interface get a number of events from the kernel at once. +Since the number retrieved can impact performance, it can be tuned by modifying this value. +The engines enforce a lower limit of 20. + +## CONFIG_OPERCMDS + +* **Type:** boolean +* **Default:** `FALSE` + +Since u2.10.11, several new oper-only features have been added that involve changes to the server<->server protocol. +This configuration option provides a single switch to prevent the use of these features until the entire network has been upgraded. +It is not required that all servers set this to `TRUE` in order for the features to be used, as long as all servers are running u2.10.11 or above. + +Capability negotiation itself is documented in `doc/readme.cap.md`. + +## CAP_ACCOUNTNOTIFY + +* **Type:** boolean +* **Default:** `TRUE` + +When `TRUE`, advertise and allow clients to negotiate the IRCv3 `account-notify` capability. + +When `FALSE`, the capability is not offered. + +## CAP_AWAYNOTIFY + +* **Type:** boolean +* **Default:** `TRUE` + +When `TRUE`, advertise and allow clients to negotiate the IRCv3 `away-notify` capability. + +When `FALSE`, the capability is not offered. + +## CAP_CHGHOST + +* **Type:** boolean +* **Default:** `TRUE` + +When `TRUE`, advertise and allow clients to negotiate the IRCv3 `chghost` capability. + +When `FALSE`, the capability is not offered. + +## CAP_ECHOMESSAGE + +* **Type:** boolean +* **Default:** `TRUE` + +When `TRUE`, advertise and allow clients to negotiate the IRCv3 `echo-message` capability. + +When `FALSE`, the capability is not offered. + +## CAP_EXTJOIN + +* **Type:** boolean +* **Default:** `TRUE` + +When `TRUE`, advertise and allow clients to negotiate the IRCv3 `extended-join` capability. + +When `FALSE`, the capability is not offered. + +## CAP_INVITENOTIFY + +* **Type:** boolean +* **Default:** `TRUE` + +When `TRUE`, advertise and allow clients to negotiate the IRCv3 `invite-notify` capability. + +When `FALSE`, the capability is not offered. + +## CAP_UHNAMES + +* **Type:** boolean +* **Default:** `TRUE` + +When `TRUE`, advertise and allow clients to negotiate the IRCv3 `userhost-in-names` capability. + +When `FALSE`, the capability is not offered. + +## CAP_MESSAGE_TAGS + +* **Type:** boolean +* **Default:** `TRUE` + +When `TRUE`, advertise and allow clients to negotiate the IRCv3 `message-tags` capability. + +When `FALSE`, the capability is not offered. + +## CAP_SERVER_TIME + +* **Type:** boolean +* **Default:** `TRUE` + +When `TRUE`, advertise and allow clients to negotiate the IRCv3 `server-time` capability. + +When `FALSE`, the capability is not offered. + +## CAP_ACCOUNT_TAG + +* **Type:** boolean +* **Default:** `TRUE` + +When `TRUE`, advertise and allow clients to negotiate the IRCv3 `account-tag` capability. + +When `FALSE`, the capability is not offered. + +## CAP_SASL + +* **Type:** boolean +* **Default:** `TRUE` + +When `TRUE`, allow the IRCv3 `sasl` capability to be offered when SASL authentication is otherwise available. + +When `FALSE`, `sasl` is never advertised, even if a SASL service is configured. +See `doc/readme.sasl.md`. + +## CLIENTTAGDENY + +* **Type:** string +* **Default:** `*` + +Controls which client-only message tags (keys beginning with `+`) are accepted and relayed. +The value is also advertised to clients via the `CLIENTTAGDENY` ISUPPORT token. +A comma-separated list is interpreted as follows: + +- An empty value allows all client-only tags. +- `"*"` denies all client-only tags. +- With `"*"`, entries of the form `"-tag"` are exceptions and are allowed. +- Without `"*"`, listed tag names are denied and all others are allowed. + +## STRICT_USERNAME + +* **Type:** boolean +* **Default:** `FALSE` + +ircu checks the composition of usernames and reject usernames matching certain rules. +Enabling this feature will reject users with usernames matching any of the following additional criterias: + +- If mixed case, first must be capital, but no more than three; but if three capitals, they must all be leading. +- If two different groups of digits, one must be either at the start or end. +- No more than two groups of digits. +- Final character must not be punctuation. + +## HIS_MAP + +* **Type:** boolean +* **Default:** `TRUE` + +As per UnderNet CFV-165, this removes `/MAP` from users. + +## HIS_SNOTICES + +* **Type:** boolean +* **Default:** `TRUE` + +As per UnderNet CFV-165, this removes server notices from users. + +## HIS_SNOTICES_OPER_ONLY + +* **Type:** boolean +* **Default:** `TRUE` + +As per UnderNet CFV-165, this removes server notices from users. + +## HIS_DEBUG_OPER_ONLY + +* **Type:** boolean +* **Default:** `TRUE` + +As per UnderNet CFV-165, this removes server wallops from users. + +## HIS_WALLOPS + +* **Type:** boolean +* **Default:** `TRUE` + +As per UnderNet CFV-165, this removes operator wallops from users. + +## HIS_LINKS + +* **Type:** boolean +* **Default:** `TRUE` + +As per UnderNet CFV-165, this removes `/LINKS` from users. + +## HIS_TRACE + +* **Type:** boolean +* **Default:** `TRUE` + +As per UnderNet CFV-165, this removes `/TRACE` from users. + +## HIS_STATS_a + +* **Type:** boolean +* **Default:** `TRUE` + +As per UnderNet CFV-165, this removes `/STATS a` from users. + +## HIS_STATS_c + +* **Type:** boolean +* **Default:** `TRUE` + +As per UnderNet CFV-165, this removes `/STATS c` from users. + +## HIS_STATS_C + +* **Type:** boolean +* **Default:** `TRUE` + +As per UnderNet CFV-165, this removes `/STATS C` from users. + +## HIS_STATS_d + +* **Type:** boolean +* **Default:** `TRUE` + +As per UnderNet CFV-165, this removes `/STATS d` from users. + +## HIS_STATS_e + +* **Type:** boolean +* **Default:** `TRUE` + +As per UnderNet CFV-165, this removes `/STATS e` from users. + +## HIS_STATS_f + +* **Type:** boolean +* **Default:** `TRUE` + +As per UnderNet CFV-165, this removes `/STATS f` from users. + +## HIS_STATS_g + +* **Type:** boolean +* **Default:** `TRUE` + +As per UnderNet CFV-165, this removes `/STATS g` from users. + +## HIS_STATS_i + +* **Type:** boolean +* **Default:** `TRUE` + +As per UnderNet CFV-165, this removes `/STATS i` from users. + +## HIS_STATS_j + +* **Type:** boolean +* **Default:** `TRUE` + +As per UnderNet CFV-165, this removes `/STATS j` from users. + +## HIS_STATS_J + +* **Type:** boolean +* **Default:** `TRUE` + +As per UnderNet CFV-165, this removes `/STATS J` from users. + +## HIS_STATS_k + +* **Type:** boolean +* **Default:** `TRUE` + +As per UnderNet CFV-165, this removes `/STATS k` from users. + +## HIS_STATS_l + +* **Type:** boolean +* **Default:** `TRUE` + +As per UnderNet CFV-165, this removes `/STATS l` from users. + +## HIS_STATS_L + +* **Type:** boolean +* **Default:** `TRUE` + +As per UnderNet CFV-165, this removes `/STATS L` from users. + +## HIS_STATS_M + +* **Type:** boolean +* **Default:** `TRUE` + +As per UnderNet CFV-165, this removes `/STATS M` from users. + +## HIS_STATS_m + +* **Type:** boolean +* **Default:** `TRUE` + +As per UnderNet CFV-165, this removes `/STATS m` from users. + +## HIS_STATS_o + +* **Type:** boolean +* **Default:** `TRUE` + +As per UnderNet CFV-165, this removes `/STATS o` from users. + +## HIS_STATS_p + +* **Type:** boolean +* **Default:** `TRUE` + +As per UnderNet CFV-165, this removes `/STATS p` from users. + +## HIS_STATS_q + +* **Type:** boolean +* **Default:** `TRUE` + +As per UnderNet CFV-165, this removes `/STATS q` from users. + +## HIS_STATS_r + +* **Type:** boolean +* **Default:** `TRUE` + +As per UnderNet CFV-165, this removes `/STATS r` from users. + +## HIS_STATS_R + +* **Type:** boolean +* **Default:** `TRUE` + +As per UnderNet CFV-165, this removes `/STATS R` from users. + +## HIS_STATS_s + +* **Type:** boolean +* **Default:** `TRUE` + +As per UnderNet CFV-165, this removes `/STATS s` from users. + +## HIS_STATS_S + +* **Type:** boolean +* **Default:** `TRUE` + +As per UnderNet CFV-165, this removes `/STATS S` from users. + +## HIS_STATS_t + +* **Type:** boolean +* **Default:** `TRUE` + +As per UnderNet CFV-165, this removes `/STATS t` from users. + +## HIS_STATS_T + +* **Type:** boolean +* **Default:** `TRUE` + +As per UnderNet CFV-165, this removes `/STATS T` from users. + +## HIS_STATS_u + +* **Type:** boolean +* **Default:** `FALSE` + +As per UnderNet CFV-165, this allows users to perform `/STATS u`. + +## HIS_STATS_U + +* **Type:** boolean +* **Default:** `TRUE` + +As per UnderNet CFV-165, this removes `/STATS U` from users. + +## HIS_STATS_v + +* **Type:** boolean +* **Default:** `TRUE` + +As per UnderNet CFV-165, this removes `/STATS v` from users. + +## HIS_STATS_w + +* **Type:** boolean +* **Default:** `FALSE` + +As per UnderNet CFV-165, this allows users to perform `/STATS w`. + +## HIS_STATS_W + +* **Type:** boolean +* **Default:** `TRUE` + +As per UnderNet CFV-165, this removes `/STATS W` from users. + +## HIS_STATS_x + +* **Type:** boolean +* **Default:** `TRUE` + +As per UnderNet CFV-165, this removes `/STATS x` from users. + +## HIS_STATS_y + +* **Type:** boolean +* **Default:** `TRUE` + +As per UnderNet CFV-165, this removes `/STATS y` from users. + +## HIS_STATS_z + +* **Type:** boolean +* **Default:** `TRUE` + +As per UnderNet CFV-165, this removes `/STATS z` from users. + +## HIS_STATS_IAUTH + +* **Type:** boolean +* **Default:** `TRUE` + +As per UnderNet CFV-165, this disables `/STATS IAUTH` and `/STATS IAUTHCONF` from users. + +## HIS_WEBIRC + +* **Type:** boolean +* **Default:** `TRUE` + +As per UnderNet CFV-165, this disables display of WebIRC status in `/WHOIS` replies (unless the client is asking about itself) and the ^ prefix for WebIRC usernames. + +## HIS_WHOIS_SERVERNAME + +* **Type:** boolean +* **Default:** `TRUE` + +As per UnderNet CFV-165, this removes server names in replies to `/WHOIS`. + +## HIS_WHOIS_IDLETIME + +* **Type:** boolean +* **Default:** `TRUE` + +As per UnderNet CFV-165, this removes idle time in replies to `/WHOIS`. + +## HIS_WHO_SERVERNAME + +* **Type:** boolean +* **Default:** `TRUE` + +As per UnderNet CFV-165, this removes server names in replies to `/WHO`. + +## HIS_WHO_HOPCOUNT + +* **Type:** boolean +* **Default:** `TRUE` + +As per UnderNet CFV-165, this replaces hopcount to a static 3 in replies to `/WHO`. + +## HIS_MODEWHO + +* **Type:** boolean +* **Default:** `TRUE` + +As per UnderNet CFV-165, this doesn't show which server performed a channel mode change. + +## HIS_BANWHO + +* **Type:** boolean +* **Default:** `TRUE` + +As per UnderNet CFV-165, this doesn't show which server set a ban. + +## HIS_KILLWHO + +* **Type:** boolean +* **Default:** `TRUE` + +As per UnderNet CFV-165, this doesn't show which server or oper performed a kill. + +## HIS_REWRITE + +* **Type:** boolean +* **Default:** `TRUE` + +As per UnderNet CFV-165, this remaps remote numerics to come from the local server. + +## HIS_REMOTE + +* **Type:** boolean +* **Default:** `TRUE` + +As per UnderNet CFV-165, this disallows remote queries. +(*sob!*) + +## HIS_NETSPLIT + +* **Type:** boolean +* **Default:** `TRUE` + +As per UnderNet CFV-165, this removes server names in net break sign-offs. + +## HIS_WHOIS_LOCALCHAN + +* **Type:** boolean +* **Default:** `TRUE` + +As per UnderNet CFV-165, this removes local channels in replies to `/WHOIS`. + +## HIS_SERVERNAME + +* **Type:** string +* **Default:** "*.undernet.org" + +As per UnderNet CFV-165, this is the "name" of the server shown to users on a `/WHOIS` of another user. + +## HIS_SERVERINFO + +* **Type:** string +* **Default:** "The Undernet Underworld" + +As per UnderNet CFV-165, this is the "info" of the server shown to users on a `/WHOIS` of another user. + +## HIS_URLSERVERS + +* **Type:** string +* **Default:** "http://www.undernet.org/servers.php" + +As per UnderNet CFV-165, this is the URL shown to users when they do a `/MAP` or `/LINKS`. + +## NETWORK + +* **Type:** string +* **Default:** "UnderNet" + +This defines the network name as reported in the 005 "supported features" numeric, and as used by the "Failed to deliver" message. + +## URL_CLIENTS + +* **Type:** string +* **Default:** "ftp://ftp.undernet.org/pub/irc/clients" + +This defines a URL that users may visit to find compatible IRC clients. + +## URLREG + +* **Type:** string +* **Default:** "http://cservice.undernet.org/live/" + +This defines a URL that is used in server response 477 (`ERR_NEEDREGGEDNICK`) to let users know which website they must visit to obtain a proper account for authentication. + +## NICKLEN + +* **Type:** integer +* **Default:** 12 + +This is the allowed length of the nickname length. +It may not be larger than the `NICKLEN` #define, and should usually be the same length. +The real purpose of this feature is to permit easy increases in nickname length for a network. + +## IRCD_RES_RETRIES + +* **Type:** integer +* **Default:** 2 + +This is the number of attempts the irc daemon's resolver will have at trying to solicit a response from the DNS server. + +## IRCD_RES_TIMEOUT + +* **Type:** integer +* **Default:** 4 + +When a DNS query is sent, the irc daemon's resolver will wait this many seconds for a reply. +After this timeout has expired, it will retry again, for as many retries as `IRCD_RES_RETRIES` allows. +This can be cut short by `AUTH_TIMEOUT` expiring. + +NOTE: Has no effect when using the adns resolver. + +## DNS_TCP_MAXCONN + +* **Type:** integer +* **Default:** 256 + +Maximum number of concurrent DNS-over-TCP connections used when a UDP response is truncated (TC=1). +This bounds file-descriptor and nameserver load if many clients trigger TCP retries. +Excess TC=1 lookups fail that client's hostname check instead of opening another TCP session. + +Set to 0 for no limit. + +## AUTH_TIMEOUT + +* **Type:** integer +* **Default:** 9 + +This is the maximum number of seconds to wait for the ident lookup and the DNS query to succeed. +On older (pre 2.10.11.06) servers this was hard coded to 60 seconds. + +## WEBSOCKET_KEEPALIVE + +* **Type:** integer +* **Default:** 0 (disabled) + +If greater than zero, the server sends an RFC 6455 WebSocket Ping frame to registered clients on WebSocket listener connections at this interval (in seconds). +This is for transport / idle TCP keepalive only; it does not replace IRC `PING`/`PONG` (see `PINGFREQUENCY` and related settings). + +## WEBSOCKET_ALLOWED_ORIGINS + +* **Type:** string +* **Default:** empty (all origins allowed) + +If set, WebSocket handshakes are accepted only when their HTTP Origin header exactly matches one of the space- or comma-separated entries in this list (case-insensitive); a handshake with a non-matching or missing Origin is rejected. +When empty (the default), the Origin header is not checked and any origin may connect, which is the traditional behavior. + +## IPCHECK_CLONE_LIMIT + +* **Type:** integer +* **Default:** 4 + +The number of times you are allowed to connect within `IPCHECK_CLONE_PERIOD` seconds before you are considered abusing the server and throttled. + +## IPCHECK_CLONE_PERIOD + +* **Type:** integer +* **Default:** 40 + +The number of seconds you are allowed to connect `IPCHECK_CLONE_LIMIT` times within before you are considered abusing the server and throttled. +For instance if you set `IPCHECK_CLONE_LIMIT` to 1, and `IPCHECK_CLONE_PERIOD` to 10, then a user is only allowed to connect once in 10s, if they connect again within 10s, then they are considered to be connecting too fast and they are throttled. + +## IPCHECK_48_CLONE_LIMIT + +* **Type:** integer +* **Default:** 50 + +This is a limit that works like `IPCHECK_CLONE_LIMIT`, but for all clients connecting from a given IPv6 /48 block. + +## IPCHECK_48_CLONE_PERIOD + +* **Type:** integer +* **Default:** 10 + +This is a timer that works like `IPCHECK_CLONE_PERIOD`, but for all clients connecting from a given IPv6 /48 block. +The number of connection attempts allowed in this period is given by the `IPCHECK_48_CLONE_LIMIT` feature. + +## IPCHECK_CLONE_DELAY + +* **Type:** integer +* **Default:** 600 + +The number of seconds grace after restarting the server before the throttle code kicks in. + +Even if a user connects repetitively during this period, they will never get throttled. +This is so after a restart users on a multiuser box can all connect to a server simultaniously without being considered an attack. + +## SOCKSENDBUF + +* **Type:** integer +* **Default:** 61440 + +The send window size used for connections to other servers. + +## SOCKRECVBUF + +* **Type:** integer +* **Default:** 61440 + +The receive window size used for connections to other servers. + +## ANNOUNCE_INVITES + +* **Type:** boolean +* **Default:** `FALSE` + +If set, send `RPL_ISSUEDINVITE` (345) to a channel's operators to announce when someone is invited to the channel. + +## LOCAL_CHANNELS + +* **Type:** boolean +* **Default:** `TRUE` + +If set, allow users to create local channels. + +## TOPIC_BURST + +* **Type:** boolean +* **Default:** `TRUE` + +Send during burst the current topic, nick of person who set the topic and topic timestamp. + +## AWAY_BURST + +* **Type:** boolean +* **Default:** `TRUE` + +Send the away message for clients flagged as away during burst. + +## DISABLE_GLINES + +* **Type:** boolean +* **Default:** `FALSE` + +When `TRUE`, G-lines are ignored: they are not applied to connecting users and do not disconnect matching clients. +Use this only for testing or emergency recovery. + +## DISABLE_SLINES + +* **Type:** boolean +* **Default:** `FALSE` + +When `TRUE`, S-line (spamfilter) processing is disabled entirely, regardless of netconf S-line server settings. +See `doc/readme.sline.md`. + +## JOIN_TARGET + +* **Type:** boolean +* **Default:** `FALSE` + +Controls how `JOIN` is handled when a client hits the target-change rate limit. + +When `FALSE` (the default), the join is still allowed but the membership is marked as a delayed target. + +When `TRUE`, the join is rejected with `ERR_TARGETTOOFAST` instead. + +## CHANNELLEN + +* **Type:** integer +* **Default:** 200 + +This is the allowed length of locally created channels. +It may not be larger than the `CHANNELLEN` #define. +Like the `NICKLEN` feature, this is intended to ease changes in channel name length across a network. + +## OPLEVELS + +* **Type:** boolean +* **Default:** `FALSE` + +This allows local users to set the `+A` and `+U` modes (admin and user passwords, respectively) on channels where they are marked as channel managers. +This feature must be disabled until all servers on the network are able to interpret and handle these modes correctly. + +## TLS_SYSTEMCA + +* **Type:** boolean +* **Default:** `TRUE` + +When `TRUE`, TLS connections whose `Port` or `Connect` block does not set `tls systemca` and does not set `tls cacertfile` or `tls cacertdir` will load the operating system's trusted CA certificate store. +Per-block TLS trust settings are documented in `doc/example.conf`. + +## NETWORK_FEATURES + +* **Type:** boolean +* **Default:** `TRUE` + +When `TRUE`, this server emits non-backwards-compatible S2S extensions: TLS certificate fingerprints on `NICK`/umode bursts, relay of remote `OPMODE +x` toward a user's home server, relay of `ACCOUNT` updates for users who are already authenticated (e.g. account flag changes), IRCv3 `message-tags` prefixes on server links, and `TAGMSG` (`TM`) to servers. +Set `FALSE` while some peers still run older ircu that cannot parse those fields, then turn it back on once the network is fully upgraded. +Peers on u2.10.12.19 and earlier protocol_violate on a second `ACCOUNT` for an already-authed nick; u2.10.13.0 tolerates same-name updates locally. +Inbound extensions are still accepted when this is `FALSE` (`TAGMSG` is delivered to local clients only). + +Federating `@time=` specifically is controlled by `NETWORK_TIME`. + +## NETWORK_TIME + +* **Type:** boolean +* **Default:** `TRUE` + +When `TRUE`, this server invents and forwards `@time=` on P10 for client-visible events (subject to `NETWORK_FEATURES`). + +When `FALSE`, time is not sent on S2S; clients that negotiated `server-time` or `message-tags` receive a stamp based on CurrentTime at local delivery instead of any upstream time tag. + +## TLS_CIPHERS + +* **Type:** string +* **Default:** `""` + +This specifies the default list of ciphers to use. +This list is used for outbound connections to servers with no `tls ciphers` directive in their `Connect` blocks, and for inbound connections on TLS-only ports with no `tls ciphers` directive in their `Port` blocks. + +This cipher list is interpreted by, and thus depends on, the TLS library in use: + +- For all libraries, an empty string represents use of the library's default cipher suites. +- For OpenSSL, it is parsed as "L1 L2" (two lists, separated by spaces) where L1 is used for TLSv1.2 and below (with SSL_set_cipher_list()) and L2 is used for TLSv1.3 (with SSL_set_ciphersuites()). +- For GnuTLS, it is parsed as a "priority string" by the function gnutls_priority_init() and then applied to sessions. +- For OpenBSD's libtls, it is passed to tls_config_set_ciphers(). + +## ZANNELS + +* **Type:** boolean +* **Default:** `FALSE` + +This preserves empty channels with no admin password so that it is impractical to become the channel manager by clearing out the channel. +It must be set to `FALSE` if there are both 2.10.11.x servers and 2.10.12.y servers on the network where y < 4. +It should be set to `TRUE` whenever the `OPLEVELS` features is `TRUE`. diff --git a/doc/readme.gline b/doc/readme.gline deleted file mode 100644 index bbc00b49..00000000 --- a/doc/readme.gline +++ /dev/null @@ -1,124 +0,0 @@ -GLINE documentation, last updated on 17 Mar 2007 - -For an ordinary user, the syntax is: - - GLINE [] - -If is given, and if a G-line for that server exists, all the -information about that G-line is displayed. If is not given, -an error is returned. - -For an operator, the syntax is: - - GLINE [[!][+|-|>|<] [] [ [:]]] - -There are a total of 10 basic forms of the GLINE command. If no -arguments are given, all existing G-lines will be listed; if only - is given, the behavior is the same as for an ordinary user. -The remaining forms allow G-lines to be set, manipulated, or possibly -destroyed. - -* Local G-lines. - -Opers may set or remove G-lines that only apply to a specific server. -When the parameter is not given, the specific server will be -the local server; otherwise, it will be taken to be a remote server, -and the G-line operations will take place there, if the oper has the -GLINE privilege. When is preceded with the '+' character, the -G-line will be added, and and are required; when - is preceded with the '-' character, the G-line will be removed, -and and are not required. The '<' and '>' -character prefixes are not valid for local G-lines. - -* Local modifications to global G-lines. - -Opers may locally activate or deactivate global G-lines. In this -mode, is interpreted as referencing an existing G-line, and -will be preceded by either '<' (to locally deactivate the G-line) or -'>' (to locally activate the G-line). This local state overrides the -global state of the G-line, and persists until there is a global state -change to the G-line, or until the G-line expires. The -and arguments are not required, but may be given if -the oper desires to make the appropriate change on a remote -server--note that the oper will need the GLINE privilege for this. - -* Global G-lines. - -Opers may, if they have the GLINE privilege, set and manipulate global -G-lines on the network. To create a new G-line, the oper must prefix -the with either '+' (for globally activated G-lines) or '-' -(for globally deactivated G-lines). Additionally, must be -given as "*", and the and parameters are -required. If the G-line already exists, it will be modified to match -the new global status, , and . - -When the G-line already exists, an oper may activate or deactivate it -simply by setting to "*" and prefixing the with either -"+" (to activate the G-line) or "-" (to deactivate it). If it is -desired to simply modify the expiration time or reason, without -changing the activation status, specify without any prefix, set - to "*", and provide the updated and optionally an -updated . - -* Privilege notes. - -Note that, for all locally-restricted G-line changes, such as locally -activating a G-line or creating a local G-line, the oper must have the -LOCAL_GLINE privilege. For any other G-line change, including -locally-restricted changes on remote servers, the server's -CONFIG_OPERCMDS privilege must be enabled and the oper must have the -GLINE privilege. There are also restrictions to prevent an oper from -setting a G-line that is too wide; in some cases, those restrictions -may be overridden by prefixing the parameter with the "!" -character, IF the operator has the WIDE_GLINE privilege. - -For a server, the syntax is: - - GL [!][+|-|>|<] [] [] - [] [:] - -There are a total of 8 basic forms of the GL command. The primary -innovation is the addition of the parameter, which -specifies a lifetime for the G-line record which may be longer than -the expiration time. will be monotonically increasing, -enabling to be modified in any way desirable. - -* Local G-lines. - -Remote servers, or opers on them, may remotely set local G-lines on -the local server. To create a local G-line, will be set to -the numeric of the local server, and must be preceded by '+' -(optionally preceded by '!' if the origin desires to override some -safety settings). The and parameters are -required. The and parameters will be ignored if -present, allowing backwards compatibility with ircu2.10.12.10 and -prior versions. Removing local G-lines is similar-- must be -preceded by '-', and all other parameters are ignored to allow -backwards compatibility. - -* Local modifications to global G-lines. - -Remote servers, or opers on them, may also locally activate or -deactivate a global G-line on the local server. The must be -set to the numeric of the local server, and must be preceded by -either '<' (to locally deactivate the G-line) or '>' (to locally -activate the G-line). This local state overrides the global state of -the G-line, and persists until there is a global state change to the -G-line, or until the G-line expires. No other parameters are -necessary in this mode, and will be ignored if present. - -* Global G-lines. - -For creation and manipulation of global G-lines, the -parameter must be set to "*". If the G-line does not exist, and if - is given, the G-line will be created with the specified -expiration and (the latter defaulting to "No reason" if not -present). Otherwise, the G-line will be updated according to the -available parameters. The rules are similar to those for oper-issued -global G-lines, with the addition of a parameter, which is a -monotonically increasing serial number for the G-line, and an optional - parameter that specifies a monotonically increasing -lifetime for the G-line record. Note that, for existing G-lines where -only state changes (global activation or deactivation) are necessary, -only is required; must be specified for all -other forms of the GL command. diff --git a/doc/readme.gline.md b/doc/readme.gline.md new file mode 100644 index 00000000..4148d696 --- /dev/null +++ b/doc/readme.gline.md @@ -0,0 +1,154 @@ +# GLINE documentation + +## Mask forms + +A G-line mask may take any of the following forms: + +| Form | Meaning | +|------|---------| +| `user@host` | Matches a user by ident and hostname; wildcards allowed. | +| `user@ip/cidr` | Matches a user by ident and IP prefix. | +| `$R` | Matches on the real name ("GECOS") field. | +| `#channel` | A BADCHAN: forbids the channel itself. Requires the BADCHAN (or LOCAL_BADCHAN for local ones) privilege. | + +Any mask may be prefixed with `!` to force a G-line that would +otherwise be rejected as too wide, if the operator has the WIDE_GLINE +privilege. Expiration is limited to `GLINE_MAX_EXPIRE` (7 days). + +## User syntax + +For an ordinary user, the syntax is: + +``` +GLINE [] +``` + +If `` is given, and if a G-line for that mask exists, all the +information about that G-line is displayed. If `` is not given, +an error is returned. + +## Operator syntax + +For an operator, the syntax is: + +``` +GLINE [[!][+|-|>|<] [] [ [:]]] +``` + +There are a total of 10 basic forms of the GLINE command. If no +arguments are given, all existing G-lines will be listed; if only +`` is given, the behavior is the same as for an ordinary user. +The remaining forms allow G-lines to be set, manipulated, or possibly +destroyed. + +### Local G-lines + +Opers may set or remove G-lines that only apply to a specific server. +When the `` parameter is not given, the specific server will +be the local server; otherwise, it will be taken to be a remote +server, and the G-line operations will take place there, if the oper +has the GLINE privilege. When `` is preceded with the `+` +character, the G-line will be added, and `` and `` +are required; when `` is preceded with the `-` character, the +G-line will be removed, and `` and `` are not +required. The `<` and `>` character prefixes are not valid for local +G-lines. + +### Local modifications to global G-lines + +Opers may locally activate or deactivate global G-lines. In this +mode, `` is interpreted as referencing an existing G-line, and +will be preceded by either `<` (to locally deactivate the G-line) or +`>` (to locally activate the G-line). This local state overrides the +global state of the G-line, and persists until there is a global state +change to the G-line, or until the G-line expires. The `` +and `` arguments are not required, but `` may be given +if the oper desires to make the appropriate change on a remote +server — note that the oper will need the GLINE privilege for this. + +### Global G-lines + +Opers may, if they have the GLINE privilege, set and manipulate global +G-lines on the network. To create a new G-line, the oper must prefix +the `` with either `+` (for globally activated G-lines) or `-` +(for globally deactivated G-lines). Additionally, `` must be +given as `*`, and the `` and `` parameters are +required. If the G-line already exists, it will be modified to match +the new global status, ``, and ``. + +When the G-line already exists, an oper may activate or deactivate it +simply by setting `` to `*` and prefixing the `` with +either `+` (to activate the G-line) or `-` (to deactivate it). If it +is desired to simply modify the expiration time or reason, without +changing the activation status, specify `` without any prefix, +set `` to `*`, and provide the updated `` and +optionally an updated ``. + +### Privilege notes + +For all locally-restricted G-line changes, such as locally activating +a G-line or creating a local G-line, the oper must have the +LOCAL_GLINE privilege. For any other G-line change, including +locally-restricted changes on remote servers, the server's +CONFIG_OPERCMDS feature must be enabled and the oper must have the +GLINE privilege. There are also restrictions to prevent an oper from +setting a G-line that is too wide; in some cases, those restrictions +may be overridden by prefixing the `` parameter with the `!` +character, IF the operator has the WIDE_GLINE privilege. + +## Server syntax + +For a server, the syntax is: + +``` + GL [!][+|-|>|<] [] [] [] [:] +``` + +(See also section 10.1 of `doc/p10.md` for the wire-level view of this +message, including the burst forms.) + +There are a total of 8 basic forms of the GL command. The primary +innovation is the addition of the `` parameter, which +specifies a lifetime for the G-line record which may be longer than +the expiration time. `` will be monotonically increasing, +enabling `` to be modified in any way desirable. + +### Local G-lines + +Remote servers, or opers on them, may remotely set local G-lines on +the local server. To create a local G-line, `` will be set to +the numeric of the local server, and `` must be preceded by `+` +(optionally preceded by `!` if the origin desires to override some +safety settings). The `` and `` parameters are +required. The `` and `` parameters will be ignored +if present, allowing backwards compatibility with ircu2.10.12.10 and +prior versions. Removing local G-lines is similar — `` must be +preceded by `-`, and all other parameters are ignored to allow +backwards compatibility. + +### Local modifications to global G-lines + +Remote servers, or opers on them, may also locally activate or +deactivate a global G-line on the local server. The `` must +be set to the numeric of the local server, and `` must be +preceded by either `<` (to locally deactivate the G-line) or `>` (to +locally activate the G-line). This local state overrides the global +state of the G-line, and persists until there is a global state change +to the G-line, or until the G-line expires. No other parameters are +necessary in this mode, and will be ignored if present. + +### Global G-lines + +For creation and manipulation of global G-lines, the `` +parameter must be set to `*`. If the G-line does not exist, and if +`` is given, the G-line will be created with the specified +expiration and `` (the latter defaulting to "No reason" if not +present). Otherwise, the G-line will be updated according to the +available parameters. The rules are similar to those for oper-issued +global G-lines, with the addition of a `` parameter, which is +a monotonically increasing serial number for the G-line, and an +optional `` parameter that specifies a monotonically +increasing lifetime for the G-line record. Note that, for existing +G-lines where only state changes (global activation or deactivation) +are necessary, only `` is required; `` must be +specified for all other forms of the GL command. diff --git a/doc/readme.iauth b/doc/readme.iauth deleted file mode 100644 index 6572601b..00000000 --- a/doc/readme.iauth +++ /dev/null @@ -1,507 +0,0 @@ -OVERVIEW -======== - -The iauth protocol used here is based on the one in irc2.11.1, with -minor changes to support challenge-response protocols and -login-on-connect. Reference to that version's iauth-internals.txt and -source code may be useful. For clarity, this document uses "server" -to refer to any IRC server implementing this protocol, "ircu" to refer -to Undernet ircd, and "ircd" to refer to IRCnet ircd. - -Certain messages are relayed to interested operators. ircu implements -this by using the 131072 (SNO_AUTH) server notice mask. ircd -implements this by using the &AUTH local channel. - -STARTING IAUTH -============== - -The path to the iauth program is specified in the server configuration -file. The server spawns that program when reading the configuration -file or when the previous iauth instance terminates. To protect -against a series of crashes, the server will refuse to restart an -iauth instance that it spawned in the last five seconds. A rehash -operation will clear this behavior. The server and iauth instance -communicate over the iauth instance's stdin and stdout. - -Every message from the server to the iauth instance is a single line. -The line starts with an integer client identifier. This may be -1 to -indicate no particular client or a non-negative number to indicate a -client connected to the server. - -When the server starts the iauth instance, it sends a line formatted -like "-1 M irc.example.org 20000" to indicate its name and an -exclusive upper bound on valid client identifiers. In that example, -possible client identifiers would be from 0 through 19999 inclusive. -This upper bound is called MAXCONNECTIONS in the server code. - -When the iauth instance starts, it sends a V message to indicate its -version. - -The server should provide /stats subcommands that report the iauth -instance's version, configuration and statistics. - -Line formats in both direction are IRC-like in format: space -characters separate arguments and a colon at the start of an argument -indicates that the remainder of the line is one argument. To avoid -problems, IPv6 address arguments with a leading colon may have to be -prefixed with a 0 -- for example, ::1 sent as 0::1. - -When the iauth instance sends messages that relate to a particular -client, that client is identified by three parameters from the -server's Client Introduction message (, and -). If any of these disagree with the server's current -user tables, it is an error. - -CLIENT STATES -============= - -Each client is conceptually in one of four states: GONE, REGISTER, -HURRY or NORMAL. Each client starts in the GONE state. Certain -messages from the server signal a client's transition from one state -to another, and certain messages from the iauth instance cause a state -transition. - -To be pedantic, the REGISTER state is a collection of sub-states since -certain commands must occur at most and/or at least one time during -the REGISTER state. The distinctions between these sub-states are -distracting and not important, so they are described as one state and -the repetition limitations are described for each command. - -The rationale for the HURRY state is to give explicit input to the -iauth instance as to when the server believes it has sent the complete -set of data for the client. Rather than defining the complete set of -information in this protocol document, that is left to the server. -ircd does not indicate this state. - -POLICIES AND USE CASES -====================== - -The historical application of iauth has been to block users that -appear to be drones early, before they have a chance to disrupt the -network, and without affecting other users on the same host (which -K-lines do). This protocol extends that application by adding the n -server message and by allowing challenge-response exchanges with the -client. - -Eventually it would be nice to move the DNS and ident lookups into -iauth, and remove that code from the IRC server. ircd already does -this; since ircu does not, it adds the u server message. - -For trusted proxies, this protocol gives the capability for clients -connecting through those proxies to be displayed with their actual -username, IP address and hostname. The same functions allow other -clients to use iauth-assigned spoofs, for example to hide the IP -addresses used by operators. - -This protocol allows login-on-connect, for example by clients that -send their account name and password in PASS, through the R iauth -message. - -This protocol allows iauth to assign a client to a particular class by -specifying a class name in the D or R iauth message. - -SERVER MESSAGES -=============== - -X - Example Message Description -Syntax: X -Example: 5 X arguments vary -States: REGISTER(1), HURRY, NORMAL -Next State: - -Comments: This is an example message description. Each message is a - single character. The States field indicates which states the - message may occur in and any restrictions on how many times the - message may be sent during those states (restrictions only make - sense when Next State is -). The Next State field indicates which - new state is implied by the message; a hyphen indicates no state - change is implied. This is an example, not a description of the - actual X message. -Compatibility: If we believe ircu behavior is different than ircd's, - this describes ircd's behavior or expectations. - -C - Client Introduction -Syntax: C -Example: 5 C 192.168.1.10 23367 192.168.0.1 6667 -States: GONE -Next State: REGISTER -Comments: Indicates that on accepted a client - connection from on . - -D - Client Disconnect -Syntax: D -Example: 5 D -States: REGISTER, HURRY, NORMAL -Next State: GONE -Comments: Indicates that a client is disconnecting from the server. - -N - Hostname Received -Syntax: N -Example: 5 N host-1-10.example.org -States: REGISTER(1) -Next State: - -Comments: Indicates that the server received hostname information for - a client. Only one of 'N' and 'd' is sent. - -d - Hostname Timeout -Syntax: d -Example: 5 d -States: REGISTER(1) -Next State: - -Comments: Indicates that the server did not receive hostname - information for a client in a timely fashion. Only one of 'N' and - 'd' is sent. - -P - Client Password -Syntax: P : -Example: 5 P :buddha n1rvan4 -States: REGISTER -Next State: - -Comments: Indicates the client's password information. This may be a - traditional client password, an account and pass phrase pair, or the - response to a challenge (see the iauth C message). This message is - enabled by requesting the A policy. - -U - Client Username -Syntax: U : -Example: 5 U buddha :Gautama Siddhartha -States: REGISTER(1+) -Next State: - -Comments: Indicates the client's claimed username and "GECOS" - information. This information has not been checked against identd - or DNS. This message is enabled by requesting the A policy. -Compatibility: ircd only sends the parameter. - -u - Client Username -Syntax: u -Syntax: u -Example: 5 u notbuddha -States: REGISTER(1) -Next State: - -Comments: Indicates a more reliable username for the client. -Compatibility: This is an Undernet extension and ircd does not send - it. It is enabled by the iauth instance requesting the U policy. - If the identd lookup fails for a user, no username is passed. - -n - Client Nickname -Syntax: n -Example: 5 n Buddha -States: REGISTER(1+), HURRY -Next State: - -Comments: Indicates the client's requested nickname. -Compatibility: This is an Undernet extension and ircd does not send - it. It is enabled by the iauth instance requesting the U policy. - -H - Hurry Up -Syntax: H -Example: 5 H -States: REGISTER -Next State: HURRY -Comments: Indicates that the server is ready to register the client - except for needing a response from the iauth server. -Compatibility: This is an Undernet extension and ircd does not send - it. It is enabled by the iauth instance requesting the U policy. - -T - Client Registered -Syntax: T -Example: 5 T -States: HURRY -Next State: NORMAL -Comments: Indicates the server got tired of waiting for iauth to - finish and the client is being accepted. This message should - never be sent when the R policy is in effect. -Compatibility: ircd allows this message for clients in the REGISTER - state. - -E - Error -Syntax: E : -Example: 5 E Gone -States: N/A -Next State: - -Comments: Indicates that a message received from the iauth instance - could not be rationally interpreted. This may be because the client - could not be found, the client was in an inappropriate state for the - message, or for other reasons. The argument specifies the - general type of error and provides details. - may be -1. - -M - Server Name and Capacity -Syntax: M -Example: -1 M irc.example.org 20000 -States: GONE(1) -Next State: - -Comments: Indicates the server's name and upper bound on client - identifiers. -Compatibility: ircd does not include the information. - The should be ignored: ircd sends 0 and ircu sends -1. - -X - Extension Query Reply -Syntax: X : -Example: -1 X channels.undernet.org 5/127.0.0.1/6667 :OK kev Logged in -States: N/A -Next State: - -Comments: Used to deliver the reply to an extension query to the iauth - instance. The parameter indicates the origin of the - reply. The parameter is the same as was used in the X - message from the iauth instance, and can be used to pair the reply - with the original request. The parameter contains the text - of the reply. -Compatibility: This is an Undernet extension and ircd does not send - it. - -x - Extension Query Server Not Linked -Syntax: x :Server not online -Example: -1 x channels.undernet.org 5/127.0.0.1/6667 :Server not online -States: N/A -Next State: - -Comments: Used to indicate to the iauth instance that the server - specified in the X message is not presently linked to the network. - This will not detect the extension query being lost due to a network - break, so iauth instances should further implement a timeout - mechanism for extension queries. -Compatibility: This is an Undernet extension and ircd does not send - it. - -? - Information Request -Syntax: ? -Example: -1 ? config -States: N/A -Next State: - -Comments: Request that the iauth program send a particular type of - information to the server. The predefined values for are: - config - iauth should send an "a", followed by all current "A" lines - stats - iauth should send an "s", followed by all current "S" lines - stats2 - iauth should send all current "S" lines, followed by an "s" -Compatibility: This is an Undernet extension and ircd does not send it. - -IAUTH MESSAGES -============== - -X - Example Message Description -Syntax: X -Example: X something -Notify: yes -States: N/A -Next State: N/A -Comments: This is an example message description. Each message is a - single character. If the Notify field is present and says yes, - interested operators (with SNO_AUTH set) should be notified of the - message. The States field, where present, indicate which states - accept this message. Clients in other states should ignore the - message or treat it as an error. The Next State field, where - present, indicates what the next state should be for the client. - This is an example, not a description of the actual X message. -Compatibility: If we believe ircu behavior is different than ircd's, - this describes ircd's behavior or expectations. - -> - Operator Notification -Syntax: > : -Example: > :Hello Operators! -Notify: yes -Comments: Contains a message that the iauth instance wants to send to - interested operators. - -G - Set Debug Level -Syntax: G -Example: G 1 -Notify: yes -Comments: Sets a debug level for the server's end of the iauth - conversation. When enabled, debug messages should be sent to the - same channel (group, mask, etc) as other iauth notifications. - Debug level 0 suppresses iauth-related debug output, and positive - integers enable iauth debugging messages. - -O - Set Policy Options -Syntax: O -Example: O RTAWU -Notify: yes -Comments: Sets policy options for the iauth conversation. Old policy - options should be forgotten. Valid policy options are: - A - Send username and password information. - This causes the server to send the U and P messages. - R - Require clients to be approved before registering them. - When this policy is in effect, it affects the behavior - of a registration timeout; for details, see the documentation - for the T server message. - T - When the R policy is in effect and the iauth service does not - respond for a client, this causes the server to count the number - of clients refused, to send a warning message to interested - operators periodically, and to send the count of rejected users - to interested operators when the iauth instance responds again. - U - Send nickname, confirmed username and hurry information. - This causes the server to send the n, u and H messages. - W - Allow extra time for iauth to respond based on hostname. - When this policy is in effect and a DNS message (N or d) is - sent for a client, that client's registration timeout is - extended or reset. - S - IAuth supports the "? stats2" info request. -Compatibility: The U and A policies are an Undernet extensions and are - not recognized by ircd. - -V - iauth Program Version -Syntax: V : -Example: V :Undernet-iauthu v1.0 -Notify: yes -Comments: Indicates the iauth program version. This should only be - used in diagnostic messages, and must not change protocol behavior. - -a - Start of new configuration -Syntax: a -Example: a -Notify: yes -Comments: Indicates that a new configuration is being loaded by the - iauth instance. Any cached configuration records should be cleared. - -A - Configuration Information -Syntax: A : -Example: A * rfc931 -Notify: yes -Comments: Indicates new configuration information. - -s - Start of new statistics -Syntax: s -Example: s -Notify: yes -Comments: Indicates a new set of statistics will be sent. Any cached - statistics records should be cleared. In response to a "? stats2" - request, instead marks the end of a set of statistics. - -S - Statistics Information -Syntax: S : -Example: S rfc931 connected 0 unix 0 other 0 bad 0 out of 0 -Notify: yes -Comments: Indicates new or additional statistics information. - -o - Forced Username -Syntax: o -Example: o 5 192.168.1.10 23367 bubba -States: REGISTER, HURRY -Next State: - -Comments: Indicates that the username should be used for the specified - client even if the normal sanity-checking would prohibit the - username. - -U - Trusted Username -Syntax: U -Example: U 5 192.168.1.10 23367 buddha -States: REGISTER, HURRY -Next State: - -Comments: Indicates that the iauth instance believes is - accurate for the specified client. - -u - Untrusted Username -Syntax: u -Example: u 5 192.168.1.10 23367 enlightened_one -States: REGISTER, HURRY -Next State: - -Comments: Indicates that the iauth instance does not strongly trust - to be accurate, but has no more trusted username. - -N - Client Hostname -Syntax: N -Example: N 5 192.168.1.10 23367 buddha.example.org -States: REGISTER, HURRY -Next State: - -Comments: Indicates that the iauth instance believes the specified - client should use the hostname given. -Compatibility: This is an Undernet extension and ircd does not support - this message. - -I - Client IP Address -Syntax: I -Example: I 5 192.168.1.10 23367 127.128.129.130 -States: REGISTER, HURRY -Next State: - -Comments: Indicates that the iauth instance wants the server to - present and treat the client as using . This means that - future iauth messages relating to the client must use - as the parameter. -Compatibility: This is an Undernet extension and ircd does not support - this message. - -M - Adjust User Mode -Syntax: M + -Example: M 5 192.168.1.10 23367 +iwg -States: REGISTER, HURRY -Next State: - -Comments: Indicates a set of user mode changes to be applied to the - client. -Compatibility: This is an Undernet extension and ircd does not support - this message. - -C - Challenge User -Syntax: C : -Example: C 5 192.168.1.10 23367 :In which year did Columbus sail the ocean blue? -States: REGISTER, HURRY -Next State: - -Comments: Indicates that the challenge string should be sent to the - specified user, for example via NOTICE AUTH :*** . - The client responds by sending PASS :, which should be - relayed via the P server message. This requires that the A policy - be in effect. -Compatibility: This is an Undernet extension and ircd does not support - this message. - -k - Quietly Kill Client -Syntax: k : -Example: k 5 192.168.1.10 23367 :Open proxy found. -States: REGISTER, HURRY, NORMAL -Next State: GONE -Comments: Indicates that the specified client should be disconnected - for the reason given without notifying operators. -Compatibility: ircu does not use the same notification mechanism as - ircd, so operators are notified using SNO_CONNEXIT anyway. - -K - Kill Client -Syntax: K : -Example: K 5 192.168.1.10 23367 :We don't like you. -States: REGISTER, HURRY, NORMAL -Next State: GONE -Comments: Indicates that the specified client should be disconnected - for the reason given. Operators should be notified. - -d - "Soft" Done Checking -Syntax: d -Example: d 5 192.168.1.10 23367 -States: REGISTER, HURRY -Next State: - -Comments: Indicates that the iauth instance has no objection to letting - the specified client onto the network, but that some further work is - in process. In particular, an account stamp and/or connection class - might be available later. -Compatibility: This is an Undernet extension and ircd does not support - this message. - -D - Done Checking -Syntax: D [class] -Example: D 5 192.168.1.10 23367 -States: REGISTER, HURRY -Next State: NORMAL -Comments: Indicates that the iauth instance believes the specified - client should be allowed onto the network. If a class parameter is - given, the client should be assigned to that class. -Compatibility: Specifying the class is an Undernet extension and ircd - does not support that parameter. - -R - Registered User -Syntax: R [class] -Example: R 5 192.168.1.10 23367 Buddha -States: REGISTER, HURRY -Next State: NORMAL -Comments: Indicates that the iauth instance believes the specified - client should be allowed onto the network, pre-authenticated to - the account listed. If a class parameter is given, the client - should be assigned to that class. -Compatibility: This is an Undernet extension and ircd does not support - this message. - -X - Extension Query -Syntax: X : -Example: X channels.undernet.org 5/127.0.0.1/6667 :login kev pass -Comments: Used by the iauth instance to send an extension query to - the server specified by . The parameter is - not interpreted by the servers; it will be returned unchanged in - the extension query reply message (the X server message) and may be - used to pair the query with its reply. The parameter is - sent to . -Compatibility: This is an Undernet extension and ircd does not support - this message. diff --git a/doc/readme.iauth.md b/doc/readme.iauth.md new file mode 100644 index 00000000..a9cda50f --- /dev/null +++ b/doc/readme.iauth.md @@ -0,0 +1,730 @@ +# IAuth Protocol + +## Overview + +The iauth protocol used here is based on the one in irc2.11.1, with +changes to support challenge-response protocols and login-on-connect. +Reference to that version's iauth-internals.txt and source code may be +useful. For clarity, this document uses "server" to refer to any IRC +server implementing this protocol, "ircu" to refer to Undernet ircd, +and "ircd" to refer to IRCnet ircd. + +Certain messages are relayed to interested operators. ircu implements +this by using the 131072 (`SNO_AUTH`) server notice mask. ircd +implements this by using the &AUTH local channel. + +The implementation lives in `ircd/s_auth.c`. + +## Starting iauth + +The path to the iauth program is specified in the server configuration +file (the `IAuth` block in `ircd.conf`, see `doc/example.conf`): + +``` +IAuth { + program = "../path/to/iauth" "-n" "options go here"; +}; +``` + +The server spawns that program when reading the configuration file or +when the previous iauth instance terminates. To protect against a +series of crashes, the server will refuse to restart an iauth instance +that it spawned in the last five seconds. A rehash operation will +clear this behavior. The server and iauth instance communicate over +the iauth instance's stdin and stdout. + +Every message from the server to the iauth instance is a single line. +The line starts with an integer client identifier. This may be -1 to +indicate no particular client or a non-negative number to indicate a +client connected to the server. + +When the server starts the iauth instance, it sends a line formatted +like `-1 M irc.example.org 20000` to indicate its name and an +exclusive upper bound on valid client identifiers. In that example, +possible client identifiers would be from 0 through 19999 inclusive. +This upper bound is called MAXCONNECTIONS in the server code. + +When the iauth instance starts, it sends a V message to indicate its +version. + +The server provides `/stats` subcommands that report the iauth +instance's version, configuration and statistics. + +Line formats in both directions are IRC-like in format: space +characters separate arguments and a colon at the start of an argument +indicates that the remainder of the line is one argument. To avoid +problems, IPv6 address arguments with a leading colon may have to be +prefixed with a 0 — for example, `::1` sent as `0::1`. + +When the iauth instance sends messages that relate to a particular +client, that client is identified by three parameters from the +server's Client Introduction message (``, `` and +``). If any of these disagree with the server's current +user tables, it is an error. + +## Client states + +Each client is conceptually in one of four states: GONE, REGISTER, +HURRY or NORMAL. Each client starts in the GONE state. Certain +messages from the server signal a client's transition from one state +to another, and certain messages from the iauth instance cause a state +transition. + +To be pedantic, the REGISTER state is a collection of sub-states since +certain commands must occur at most and/or at least one time during +the REGISTER state. The distinctions between these sub-states are +distracting and not important, so they are described as one state and +the repetition limitations are described for each command. + +The rationale for the HURRY state is to give explicit input to the +iauth instance as to when the server believes it has sent the complete +set of data for the client. Rather than defining the complete set of +information in this protocol document, that is left to the server. +ircd does not indicate this state. + +## Policies and use cases + +The historical application of iauth has been to block users that +appear to be drones early, before they have a chance to disrupt the +network, and without affecting other users on the same host (which +K-lines do). This protocol extends that application by adding the n +server message and by allowing challenge-response exchanges with the +client. + +Eventually it would be nice to move the DNS and ident lookups into +iauth, and remove that code from the IRC server. ircd already does +this; since ircu does not, it adds the u server message. + +For trusted proxies, this protocol gives the capability for clients +connecting through those proxies to be displayed with their actual +username, IP address and hostname. The same functions allow other +clients to use iauth-assigned spoofs, for example to hide the IP +addresses used by operators. + +This protocol allows login-on-connect, for example by clients that +send their account name and password in PASS, through the R iauth +message. + +This protocol allows iauth to assign a client to a particular class by +specifying a class name in the D or R iauth message. + +### Special port types + +For WebIRC and Cloudflare ports the client's real IP address is only +known once the proxy has identified the client (the `WEBIRC` command +or the `CF-Connecting-IP` header). On those connections the Client +Introduction is deferred until the spoofed identity has been applied, +so iauth always sees the client's real address. WebSocket ports send +the introduction once the HTTP upgrade has completed. + +## Server messages + +### X — Example Message Description + +``` +Syntax: X +Example: 5 X arguments vary +States: REGISTER(1), HURRY, NORMAL +Next state: - +``` + +This is an example message description. Each message is a single +character. The States field indicates which states the message may +occur in and any restrictions on how many times the message may be +sent during those states (restrictions only make sense when Next State +is -). The Next State field indicates which new state is implied by +the message; a hyphen indicates no state change is implied. This is +an example, not a description of the actual X message. + +Where ircu behavior is believed to differ from ircd's, a +*Compatibility* note describes ircd's behavior or expectations. + +### C — Client Introduction + +``` +Syntax: C +Example: 5 C 192.168.1.10 23367 192.168.0.1 6667 +States: GONE +Next state: REGISTER +``` + +Indicates that `` on `` accepted a client +connection from `` on ``. + +### Z — TLS Certificate Fingerprint + +``` +Syntax: Z +Example: 5 Z 1a2b3c4d5e6f... +States: REGISTER(1) +Next state: - +``` + +Indicates the fingerprint of the client certificate the client +presented on a TLS connection. Sent immediately after the Client +Introduction, and only when the client connected over TLS and +presented a certificate. + +*Compatibility:* This is an extension in this ircu tree; neither ircd +nor stock ircu send it. + +### D — Client Disconnect + +``` +Syntax: D +Example: 5 D +States: REGISTER, HURRY, NORMAL +Next state: GONE +``` + +Indicates that a client is disconnecting from the server. + +### N — Hostname Received + +``` +Syntax: N +Example: 5 N host-1-10.example.org +States: REGISTER(1) +Next state: - +``` + +Indicates that the server received hostname information for a client. +Only one of `N` and `d` is sent. + +### d — Hostname Timeout + +``` +Syntax: d +Example: 5 d +States: REGISTER(1) +Next state: - +``` + +Indicates that the server did not receive hostname information for a +client in a timely fashion. Only one of `N` and `d` is sent. + +### P — Client Password + +``` +Syntax: P : +Example: 5 P :buddha n1rvan4 +States: REGISTER +Next state: - +``` + +Indicates the client's password information. This may be a +traditional client password, an account and pass phrase pair, or the +response to a challenge (see the iauth C message). This message is +enabled by requesting the A policy. + +### U — Client Username + +``` +Syntax: U : +Example: 5 U buddha :Gautama Siddhartha +States: REGISTER(1+) +Next state: - +``` + +Indicates the client's claimed username and "GECOS" information. This +information has not been checked against identd or DNS. This message +is enabled by requesting the A policy. + +*Compatibility:* ircd only sends the `` parameter. + +### u — Client Username + +``` +Syntax: u +Example: 5 u notbuddha +States: REGISTER(1) +Next state: - +``` + +Indicates a more reliable username for the client: the identd +response when the lookup succeeded, otherwise the claimed username +with the untrusted-username prefix applied (`~`, or `^` for an +untrusted WEBIRC user when `HIS_WEBIRC` is off). + +*Compatibility:* This is an Undernet extension and ircd does not send +it. It is enabled by the iauth instance requesting the U policy. + +### A — Client Account + +``` +Syntax: A +Example: 5 A buddha +States: REGISTER +Next state: - +``` + +Indicates that the client authenticated to an account while still +registering — for example via SASL login-on-connect. Sent when the +account is applied to the client. + +*Compatibility:* This is an extension in this ircu tree; neither ircd +nor stock ircu send it. + +### c — Capability Negotiation Started + +``` +Syntax: c +Example: 5 c +States: REGISTER +Next state: - +``` + +Indicates that the client started IRCv3 capability negotiation +(`CAP`). Registration is blocked (the client will not leave the +REGISTER/HURRY states) until negotiation ends. + +*Compatibility:* This is an extension in this ircu tree; neither ircd +nor stock ircu send it. + +### e — Capability Negotiation Ended + +``` +Syntax: e +Example: 5 e +States: REGISTER +Next state: - +``` + +Indicates that the client completed capability negotiation (`CAP +END`), unblocking registration. + +*Compatibility:* This is an extension in this ircu tree; neither ircd +nor stock ircu send it. + +### n — Client Nickname + +``` +Syntax: n +Example: 5 n Buddha +States: REGISTER(1+), HURRY +Next state: - +``` + +Indicates the client's requested nickname. + +*Compatibility:* This is an Undernet extension and ircd does not send +it. It is enabled by the iauth instance requesting the U policy. + +### H — Hurry Up + +``` +Syntax: H +Example: 5 H +States: REGISTER +Next state: HURRY +``` + +Indicates that the server is ready to register the client except for +needing a response from the iauth server. + +*Compatibility:* This is an Undernet extension and ircd does not send +it. It is enabled by the iauth instance requesting the U policy. + +### T — Client Registered + +``` +Syntax: T +Example: 5 T +States: HURRY +Next state: NORMAL +``` + +Indicates the server got tired of waiting for iauth to finish and the +client is being accepted. This message should never be sent when the +R policy is in effect. + +*Compatibility:* ircd allows this message for clients in the REGISTER +state. + +### E — Error + +``` +Syntax: E : +Example: 5 E Gone +``` + +Indicates that a message received from the iauth instance could not be +rationally interpreted. This may be because the client could not be +found, the client was in an inappropriate state for the message, or +for other reasons. The `` argument specifies the general type +of error and `` provides details. `` may be -1. + +### M — Server Name and Capacity + +``` +Syntax: M +Example: -1 M irc.example.org 20000 +States: GONE(1) +Next state: - +``` + +Indicates the server's name and upper bound on client identifiers. + +*Compatibility:* ircd does not include the `` information. +The `` should be ignored: ircd sends 0 and ircu sends -1. + +### X — Extension Query Reply + +``` +Syntax: X : +Example: -1 X channels.undernet.org 5/127.0.0.1/6667 :OK kev Logged in +``` + +Used to deliver the reply to an extension query to the iauth instance. +The `` parameter indicates the origin of the reply. The +`` parameter is the same as was used in the X message from +the iauth instance, and can be used to pair the reply with the +original request. The `` parameter contains the text of the +reply. + +On the network the query travels as a P10 `XQUERY` with the routing +token prefixed by `iauth:`; the server strips that prefix again before +relaying the reply to the iauth instance (see section 11 of +`doc/p10.md`). + +*Compatibility:* This is an Undernet extension and ircd does not send +it. + +### x — Extension Query Server Not Linked + +``` +Syntax: x :Server not online +Example: -1 x channels.undernet.org 5/127.0.0.1/6667 :Server not online +``` + +Used to indicate to the iauth instance that the server specified in +the X message is not presently linked to the network. This will not +detect the extension query being lost due to a network break, so iauth +instances should further implement a timeout mechanism for extension +queries. + +*Compatibility:* This is an Undernet extension and ircd does not send +it. + +### ? — Information Request + +``` +Syntax: ? +Example: -1 ? config +``` + +Request that the iauth program send a particular type of information +to the server. The predefined values for `` are: + +| Type | Meaning | +|------|---------| +| `config` | iauth should send an `a`, followed by all current `A` lines | +| `stats` | iauth should send an `s`, followed by all current `S` lines | +| `stats2` | iauth should send all current `S` lines, followed by an `s` | + +*Compatibility:* This is an Undernet extension and ircd does not send +it. + +## IAuth messages + +The same example-description conventions apply as for server messages. +If the Notify field says yes, interested operators (with `SNO_AUTH` +set) are notified of the message. An unrecognized command is answered +with `-1 E Garbage`. + +### > — Operator Notification + +``` +Syntax: > : +Example: > :Hello Operators! +Notify: yes +``` + +Contains a message that the iauth instance wants to send to interested +operators. + +### G — Set Debug Level + +``` +Syntax: G +Example: G 1 +Notify: yes +``` + +Sets a debug level for the server's end of the iauth conversation. +When enabled, debug messages should be sent to the same channel +(group, mask, etc) as other iauth notifications. Debug level 0 +suppresses iauth-related debug output, and positive integers enable +iauth debugging messages. + +### O — Set Policy Options + +``` +Syntax: O +Example: O RTAWU +Notify: yes +``` + +Sets policy options for the iauth conversation. Old policy options +should be forgotten. Valid policy options are: + +| Option | Meaning | +|--------|---------| +| `A` | Send username and password information. This causes the server to send the U and P messages. | +| `R` | Require clients to be approved before registering them. When this policy is in effect, it affects the behavior of a registration timeout; for details, see the documentation for the T server message. | +| `T` | When the R policy is in effect and the iauth service does not respond for a client, this causes the server to count the number of clients refused, to send a warning message to interested operators periodically, and to send the count of rejected users to interested operators when the iauth instance responds again. | +| `U` | Send nickname, confirmed username and hurry information. This causes the server to send the n, u and H messages. | +| `W` | Allow extra time for iauth to respond based on hostname. When this policy is in effect and a DNS message (N or d) is sent for a client, that client's registration timeout is extended or reset. | +| `S` | iauth supports the "? stats2" info request. | + +*Compatibility:* The U and A policies are Undernet extensions and are +not recognized by ircd. + +### V — iauth Program Version + +``` +Syntax: V : +Example: V :Undernet-iauthu v1.0 +Notify: yes +``` + +Indicates the iauth program version. This should only be used in +diagnostic messages, and must not change protocol behavior. + +### a — Start of new configuration + +``` +Syntax: a +Notify: yes +``` + +Indicates that a new configuration is being loaded by the iauth +instance. Any cached configuration records should be cleared. + +### A — Configuration Information + +``` +Syntax: A : +Example: A * rfc931 +Notify: yes +``` + +Indicates new configuration information. + +### s — Start of new statistics + +``` +Syntax: s +Notify: yes +``` + +Indicates a new set of statistics will be sent. Any cached statistics +records should be cleared. In response to a "? stats2" request, +instead marks the end of a set of statistics. + +### S — Statistics Information + +``` +Syntax: S : +Example: S rfc931 connected 0 unix 0 other 0 bad 0 out of 0 +Notify: yes +``` + +Indicates new or additional statistics information. + +### o — Forced Username + +``` +Syntax: o +Example: o 5 192.168.1.10 23367 bubba +States: REGISTER, HURRY +Next state: - +``` + +Indicates that the username should be used for the specified client +even if the normal sanity-checking would prohibit the username. + +### U — Trusted Username + +``` +Syntax: U +Example: U 5 192.168.1.10 23367 buddha +States: REGISTER, HURRY +Next state: - +``` + +Indicates that the iauth instance believes `` is accurate +for the specified client. + +### u — Untrusted Username + +``` +Syntax: u +Example: u 5 192.168.1.10 23367 enlightened_one +States: REGISTER, HURRY +Next state: - +``` + +Indicates that the iauth instance does not strongly trust `` +to be accurate, but has no more trusted username. + +### N — Client Hostname + +``` +Syntax: N +Example: N 5 192.168.1.10 23367 buddha.example.org +States: REGISTER, HURRY +Next state: - +``` + +Indicates that the iauth instance believes the specified client should +use the hostname given. + +*Compatibility:* This is an Undernet extension and ircd does not +support this message. + +### I — Client IP Address + +``` +Syntax: I +Example: I 5 192.168.1.10 23367 127.128.129.130 +States: REGISTER, HURRY +Next state: - +``` + +Indicates that the iauth instance wants the server to present and +treat the client as using ``. This means that future iauth +messages relating to the client must use `` as the `` +parameter. + +*Compatibility:* This is an Undernet extension and ircd does not +support this message. + +### M — Adjust User Mode + +``` +Syntax: M + +Example: M 5 192.168.1.10 23367 +iwg +States: REGISTER, HURRY +Next state: - +``` + +Indicates a set of user mode changes to be applied to the client. + +*Compatibility:* This is an Undernet extension and ircd does not +support this message. + +### C — Challenge User + +``` +Syntax: C : +Example: C 5 192.168.1.10 23367 :In which year did Columbus sail the ocean blue? +States: REGISTER, HURRY +Next state: - +``` + +Indicates that the challenge string should be sent to the specified +user, for example via `NOTICE AUTH :*** `. The +client responds by sending `PASS :`, which should be relayed +via the P server message. This requires that the A policy be in +effect. + +*Compatibility:* This is an Undernet extension and ircd does not +support this message. + +### k — Quietly Kill Client + +``` +Syntax: k : +Example: k 5 192.168.1.10 23367 :Open proxy found. +States: REGISTER, HURRY, NORMAL +Next state: GONE +``` + +Indicates that the specified client should be disconnected for the +reason given without notifying operators. + +*Compatibility:* ircu does not use the same notification mechanism as +ircd, so operators are notified using `SNO_CONNEXIT` anyway. + +### K — Kill Client + +``` +Syntax: K : +Example: K 5 192.168.1.10 23367 :We don't like you. +States: REGISTER, HURRY, NORMAL +Next state: GONE +``` + +Indicates that the specified client should be disconnected for the +reason given. Operators should be notified. + +### d — "Soft" Done Checking + +``` +Syntax: d +Example: d 5 192.168.1.10 23367 +States: REGISTER, HURRY +Next state: - +``` + +Indicates that the iauth instance has no objection to letting the +specified client onto the network, but that some further work is in +process. In particular, an account stamp and/or connection class +might be available later. + +*Compatibility:* This is an Undernet extension and ircd does not +support this message. + +### D — Done Checking + +``` +Syntax: D [class] +Example: D 5 192.168.1.10 23367 +States: REGISTER, HURRY +Next state: NORMAL +``` + +Indicates that the iauth instance believes the specified client should +be allowed onto the network. If a class parameter is given, the +client should be assigned to that class. + +*Compatibility:* Specifying the class is an Undernet extension and +ircd does not support that parameter. + +### R — Registered User + +``` +Syntax: R [:[:]] [class] +Example: R 5 192.168.1.10 23367 Buddha:42:0 +States: REGISTER, HURRY +Next state: NORMAL +``` + +Indicates that the iauth instance believes the specified client should +be allowed onto the network, pre-authenticated to the account listed. +The account may carry a numeric account id and a flag word, separated +by colons, which are stamped onto the client (compare the `ACCOUNT` +message in `doc/p10.md`). If a class parameter is given, the client +should be assigned to that class. + +*Compatibility:* This is an Undernet extension and ircd does not +support this message. The account id and flags are extensions in this +ircu tree. + +### X — Extension Query + +``` +Syntax: X : +Example: X channels.undernet.org 5/127.0.0.1/6667 :login kev pass +``` + +Used by the iauth instance to send an extension query to the server +specified by ``. The `` parameter is not +interpreted by the servers; it will be returned unchanged in the +extension query reply message (the X server message) and may be used +to pair the query with its reply. The `` parameter is sent to +``. + +*Compatibility:* This is an Undernet extension and ircd does not +support this message. diff --git a/doc/readme.indent b/doc/readme.indent deleted file mode 100644 index 6e02bc0f..00000000 --- a/doc/readme.indent +++ /dev/null @@ -1,9 +0,0 @@ -If you want to indent this source file, in order to convert -the source tree to the used programming style, you should use -`make indent' in the base directory. - -For this to work you need to have `indent' version 2.1.0 or higher -in your PATH. GNU indent 2.1.0 is available from all GNU sites, -its main ftp site is ftp://ftp.gnu.org/indent/. Or you can download -it directly from the webpage of its maintainer at -http://www.xs4all.nl/~carlo17/indent/ diff --git a/doc/readme.jupe b/doc/readme.jupe deleted file mode 100644 index e34dfe7e..00000000 --- a/doc/readme.jupe +++ /dev/null @@ -1,57 +0,0 @@ -JUPE documentation, last updated on 18 Mar 2000 - -For an ordinary user, the syntax is: - - JUPE [] - -If is given, and if a jupe for that server exists, all the -information about that jupe is displayed. If is not given, -all un-expired jupes are displayed. - -For an operator, the syntax is: - - JUPE [[+|-] [[] :]] - -If is not given, or if it is not prefixed by "+" or "-", the -operation is exactly the same as if it were issued by an ordinary -user. If the "+" or "-" prefixes are used, the arguments , -, and must be given, even if the jupe already -exists. If is "*" and the currently existing jupe is a local -jupe, the local jupe will be erased and recreated with the parameters -given, as described below. Otherwise, if the jupe currently exists, a -prefix of "+" will cause an inactive jupe to be activated, whereas a -prefix of "-" will cause an active jupe to be deactivated. - -If the jupe does not already exist, it is created. The -parameter is used to select whether the jupe is only to apply to a -single server (which need not be the local server) or to the whole -network; if is not given, it is assumed to be the local -server. This could be useful if a single particular link is having -problems, for instance. The parameter is a number of -seconds, not to exceed 7 days, for the jupe to exist. The -argument is mandatory and should describe why this particular jupe was -placed. - -For a server, the syntax is: - - JU (+|-) : - -The may be a server numeric or the character "*", for a -globally scoped jupe. The argument is a server name, and -must be prefixed by one of "+" (to indicate an active jupe) or "-" (to -indicate an inactive jupe). The parameter is a total -number of seconds the jupe is to live for, and is used for -versioning. Since JUPEs are propagated during netbursts, there must -be some way of resolving conflicting states, which is the reason for -this argument, and is also the reason jupes cannot be deleted, only -deactivated. The parameter indicates the reason the jupe was -placed. - -If a JUPE is received with a of "*", any jupes with local -scope are deleted, in preference for the globally scoped version. If -the jupe already exists, the values of are compared; if the -received is less than the stored , the existing -jupe is resent to the server from which the JUPE message was received; -otherwise, the jupe is activated or deactivated, depending on the - prefix. If the jupe does not currently exist, it is created -with the parameters given. diff --git a/doc/readme.jupe.md b/doc/readme.jupe.md new file mode 100644 index 00000000..392daf8d --- /dev/null +++ b/doc/readme.jupe.md @@ -0,0 +1,91 @@ +# JUPE documentation + +A jupe forbids a server name on the network: an active jupe causes any +server of that name to be refused at link time and to be squit if it +is introduced behind another link. Jupes are versioned network state: +they are propagated during net bursts and are never deleted, only +deactivated, so that the two sides of a split can reconcile. + +## User syntax + +For an ordinary user, the syntax is: + +``` +JUPE [] +``` + +If `` is given, and if a jupe for that server exists, all the +information about that jupe is displayed. If `` is not given, +all un-expired jupes are displayed. + +## Operator syntax + +For an operator, the syntax is: + +``` +JUPE [[+|-] [] :] +``` + +If `` is not given, or if it is not prefixed by `+` or `-`, +the operation is exactly the same as if it were issued by an ordinary +user. All `+`/`-` forms require the `CONFIG_OPERCMDS` feature to be +enabled, otherwise the command is rejected as disabled. + +When the `+` or `-` prefix is used, `` and `` are +required, even if the jupe already exists (they are ignored in that +case; an existing jupe's expiration and reason cannot be changed, only +its activation state). The `` parameter selects the scope: + +| Target | Meaning | Privilege | +|--------|---------|-----------| +| omitted | Local jupe on the local server | none checked (see note) | +| a server name | Local jupe on that server; forwarded there if remote | `JUPE` for a remote server, `LOCAL_JUPE` for the local one | +| `*` | Global jupe on the whole network | `JUPE` | + +Note the inconsistency in the first row: omitting `` creates +the same local jupe as naming the local server explicitly, but the +explicit form requires the `LOCAL_JUPE` privilege while the implicit +form performs no privilege check (`mo_jupe()` in `ircd/m_jupe.c`). + +If `` is `*` and the currently existing jupe is a local jupe, +the local jupe is erased and recreated as a global one with the +parameters given. Otherwise, if the jupe exists (in the requested +scope), a prefix of `+` activates it and a prefix of `-` deactivates +it. If the jupe does not exist, it is created, active or inactive +according to the prefix. + +The `` parameter is a number of seconds, greater than zero +and not exceeding `JUPE_MAX_EXPIRE` (7 days), for the jupe to exist. +The `` argument is mandatory and should describe why this +particular jupe was placed. + +## Server syntax + +For a server, the syntax is (see also section 10.2 of `doc/p10.md`): + +``` + JU [+|-] : +``` + +The `` may be a server numeric or the character `*` for a +globally scoped jupe; a jupe targeted at another server's numeric is +forwarded to that server unchanged. The `` argument is a +server name, optionally prefixed by `+` (an active jupe) or `-` (an +inactive jupe); a bare server name is treated the same as `-`. The +parameter `` is the total number of seconds the jupe is to +live for (again at most 7 days), and `` is used for +versioning. Since jupes are propagated during net bursts, there must +be some way of resolving conflicting states, which is the reason for +this argument, and is also the reason jupes cannot be deleted, only +deactivated. Six parameters are required. + +If a jupe is received with a `` of `*`, any jupe of the same +name with local scope is deleted, in preference for the globally +scoped version. If the jupe already exists, the values of `` +are compared: if the received `` is newer, the jupe is +activated or deactivated according to the `` prefix; if it is +equal, the message is a no-op; if it is *older*, the existing (newer) +jupe is resent to the server from which the message was received — +except while that link is bursting, in which case the stale update is +silently ignored. If the jupe does not currently exist, it is created +with the parameters given. diff --git a/doc/readme.log b/doc/readme.log deleted file mode 100644 index 1e635ca1..00000000 --- a/doc/readme.log +++ /dev/null @@ -1,194 +0,0 @@ -Older versions of ircd had no consistent way of logging various -actions. Some things, such as G-lines, were written out to log files -with names compiled into the server. Others could only be logged -through syslog. Some required that their log files exist beforehand. -Starting with u2.10.11, this situation has changed dramatically. - -All logging in the server is now unified through a single logging -subsystem. Unfortunately, the server still does not generate all the -logs that it could, and some more tuning is in store for the next -major release of ircd. Nevertheless, the logs that are generated are -far more consistent, and those log messages may be sent to a given -file, to syslog, or even to online operators--or any combination of -these three methods. This file is intended to describe configuration -of the logging subsystem. - -All logs are classified by a "subsystem" and a "level." The subsystem -is a major classification; each subsystem may be configured -individually. The level classification is used to indicate how -important the message is; subsystems may be configured to omit log -messages with less than a certain importance--not unlike syslog. - -Levels - -Levels are used to classify the importance of various log messages. -The most important level is the "CRIT" level; the least important is -the "DEBUG" level. Each of the levels is also mapped to a -corresponding syslog level, and some may even force generation of -certain types of server notices. Each importance level is described -below. - - * CRIT - Used for very critical notifications, such as server - termination. This is mapped to the corresponding "CRIT" syslog - priority. This will also generate server notices to the "OLDSNO" - server notice mask. - - * ERROR - Used to report important error conditions. This is mapped - to the corresponding "ERR" syslog priority. - - * WARNING - Used to warn about certain conditions. This is mapped to - the corresponding "WARNING" syslog priority. - - * NOTICE - Used for reporting important information. This is mapped - to the corresponding "NOTICE" syslog priority. - - * TRACE - Used to tracing operation of the server. This is mapped to - the corresponding "INFO" syslog priority. - - * INFO - Used for reporting unimportant but potentially useful - information. This is mapped to the corresponding "INFO" syslog - priority. - - * DEBUG - Used for reporting debugging information. This is mapped - to the corresponding "DEBUG" syslog priority. This will also - generate server notices to the "DEBUG" server notice mask. - -Subsystems - -All of the subsystems are described below, along with their default -logging configuration. There are no default log files to log to, and -the default logging level is INFO (unless the server is compiled with -debugging enabled)--this means that only notices of importance INFO or -higher will be logged. - - * SYSTEM - Used to report information that affects the server as a - whole. By default, log messages to this subsystem go nowhere. - - * CONFIG - Used to report information concerning the configuration - file. By default, log messages to this subsystem go to the default - syslog facility, which defaults to "USER," and to the "OLDSNO" - server notice mask. - - * OPERMODE - Used to report usage of /OPMODE and /CLEARMODE. By - default, log messages to this subsystem go to the "HACK4" server - notice mask. - - * GLINE - Used to report usage of /GLINE, particularly BADCHANs. By - default, log messages to this subsystem go to the "GLINE" server - notice mask. - - * JUPE - Used to report usage of /JUPE. By default, log messages to - this subsystem go to the "NETWORK" server notice mask. - - * WHO - Used to report usage of the extended features of /WHO - (/WHOX). By default, log messages to this subsystem go nowhere. - - * NETWORK - Used to report net junctions and net breaks. By default, - log messages to this subsystem go to the "NETWORK" server notice - mask. - - * OPERKILL - Used to report usage of /KILL by IRC operators. By - default, log messages to this subsystem go nowhere. - - * SERVKILL - Used to report usage of /KILL by other servers. By - default, log messages to this subsystem go nowhere. - - * USER - Used to report user sign-ons and sign-offs. By default, log - messages to this subsystem go nowhere. - - * OPER - Used to report usage of /OPER, either successfully or - unsuccessfully. By default, log messages to this subsystem go to - the "OLDREALOP" server notice mask. - - * RESOLVER - Used to report error messages or other conditions from - the resolver and authentication system. By default, log messages - to this subsystem go nowhere. - - * SOCKET - Used to report problems with sockets. By default, log - messages to this subsystem go nowhere. - - * IAUTH - Used to report connects, disconnects and errors for the - IAuth authorization mechanism. By default, log messages to this - subsystem go to the "NETWORK" server notice mask. - - * DEBUG - Used only when debugging is enabled. All log messages to - this subsystem go either to the console or to the debug log file - compiled into the server, as well as to the "DEBUG" server notice - mask. This is the only subsystem with a default log file. - -Configuration - -The true power of the logging subsystem comes from its extremely -flexible configuration. The default server facility can be -configured, as can the facility for each individual subsystem -described above. Moreover, administrators can configure the server to -log to specific files, send selected log messages to operators -subscribed to any server notice mask, and even change the default log -level for each subsystem. - -The logging subsystem has a set of tables mapping names to the -numerical values used internally. Subsystems, levels, syslog -facilities, and server notice masks are all configured using strings. -These tables even include special strings, such as "DEFAULT" and -"NONE." Each possible configuration piece is described below. - -Default Syslog Facility - -The IRC server has a default facility that it uses when sending log -messages to syslog. The default facility may be overridden for each -individual subsystem, but the default itself can be changed with an -appropriate Feature entry in the configuration file. The facility -normally defaults to "USER," but may be configured to be any of AUTH, -CRON, DAEMON, LOCAL0, LOCAL1, LOCAL2, LOCAL3, LOCAL4, LOCAL5, LOCAL6, -LOCAL7, LPR, MAIL, NEWS, USER, or UUCP. Some systems also have the -AUTHPRIV facility. To configure this default, add a Feature line to -the configuration file that looks like "LOG" = ""; - should be replaced with the string for the desired default -syslog facility. - -Log Files - -Each subsystem may be configured to send its log messages to any -single log file with a Feature entry like "LOG" = "" "FILE" -""; should be replaced with one of the subsystem names -described above, and should be a file name for the log file. -The file name may be relative to the server's data directory -("DPATH"), or it may be an absolute path name. Note that if you're -using chroot, these absolute path names will be relative to the -server's root directory. - -Logging to Syslog - -By default, except for the CONFIG subsystem, no logs are sent to -syslog. This can be overridden using an Feature entry like "LOG" = -"" "FACILITY" ""; , as above, should be -replaced with one of the subsystem names described above, and - must be one of the facility strings mentioned under -"Default Syslog Facility." The facility string may also be "NONE," to -turn off syslog for that subsystem, and "DEFAULT," to use the server's -default facility. Please don't confuse a DEFAULT facility with the -default for a particular subsystem; only the CONFIG subsystem defaults -to DEFAULT, whereas all the rest default to NONE. - -Logging via Server Notices - -Log messages can be sent to online IRC operators. Many subsystems -actually default to this behavior, in fact. For security, log -messages containing IP addresses or other extremely sensitive data -will never be sent via server notices, but all others can be sent to a -specific server notice mask. (For more information about server -notice masks, please see doc/snomask.html.) The available mask names -are OLDSNO, SERVKILL, OPERKILL, HACK2, HACK3, UNAUTH, TCPCOMMON, -TOOMANY, HACK4, GLINE, NETWORK, IPMISMATCH, THROTTLE, OLDREALOP, -CONNEXIT, and DEBUG. The special mask name "NONE" inhibits sending of -server notices for a particular subsystem. The Feature entry for this -configuration looks like "LOG" = "" "SNOMASK" ""; again, - is one of the subsystems described above, and is one -of the mask names. - -Setting Minimum Logging Level - -The minimum log level for a particular subsystem may be set with an -Feature entry like "LOG" = "" "LEVEL" ""; here, - is yet again one of the subsystems described above, and - is one of the level names, also described above. diff --git a/doc/readme.log.md b/doc/readme.log.md new file mode 100644 index 00000000..7879ecba --- /dev/null +++ b/doc/readme.log.md @@ -0,0 +1,151 @@ +# Logging + +Older versions of ircd had no consistent way of logging various +actions. Some things, such as G-lines, were written out to log files +with names compiled into the server. Others could only be logged +through syslog. Some required that their log files exist beforehand. +Starting with u2.10.11, this situation changed dramatically. + +All logging in the server is unified through a single logging +subsystem. The log messages may be sent to a given file, to syslog, +or even to online operators — or any combination of these three +methods. This file describes the configuration of the logging +subsystem, implemented in `ircd/ircd_log.c`. + +All logs are classified by a "subsystem" and a "level." The subsystem +is a major classification; each subsystem may be configured +individually. The level classification is used to indicate how +important the message is; subsystems may be configured to omit log +messages with less than a certain importance — not unlike syslog. + +## Levels + +Levels are used to classify the importance of various log messages. +The most important level is CRIT; the least important is DEBUG. Each +level maps to a corresponding syslog priority, and some also force +generation of certain types of server notices. + +| Level | Used for | Syslog priority | Server notices | +|-------|----------|-----------------|----------------| +| CRIT | Very critical notifications, such as server termination | CRIT | `OLDSNO` mask | +| ERROR | Important error conditions | ERR | | +| WARNING | Warnings about certain conditions | WARNING | | +| NOTICE | Important information | NOTICE | | +| TRACE | Tracing the operation of the server | INFO | | +| INFO | Unimportant but potentially useful information | INFO | | +| DEBUG | Debugging information | DEBUG | `DEBUG` mask | + +## Subsystems + +All of the subsystems are listed below, along with their default +logging configuration. There are no default log files to log to, and +the default logging level is INFO (unless the server is compiled with +debugging enabled) — this means that only notices of importance INFO +or higher will be logged. + +| Subsystem | Used for | Default destination | +|-----------|----------|---------------------| +| SYSTEM | Information that affects the server as a whole | nowhere | +| CONFIG | Information concerning the configuration file | default syslog facility and the `OLDSNO` server notice mask | +| OPERMODE | Usage of /OPMODE and /CLEARMODE | `HACK4` server notice mask | +| GLINE | Usage of /GLINE, particularly BADCHANs | `GLINE` server notice mask | +| JUPE | Usage of /JUPE | `NETWORK` server notice mask | +| WHO | Usage of the extended features of /WHO (/WHOX) | nowhere | +| NETWORK | Net junctions and net breaks | `NETWORK` server notice mask | +| OPERKILL | Usage of /KILL by IRC operators | nowhere | +| SERVKILL | Usage of /KILL by other servers | nowhere | +| USER | User sign-ons and sign-offs | nowhere | +| OPER | Usage of /OPER, either successfully or unsuccessfully | `OLDREALOP` server notice mask | +| RESOLVER | Error messages or other conditions from the resolver and authentication system | nowhere | +| SOCKET | Problems with sockets | nowhere | +| IAUTH | Connects, disconnects and errors for the IAuth authorization mechanism | `NETWORK` server notice mask | +| DEBUG | Only when debugging is enabled | the console or the debug log file compiled into the server, plus the `DEBUG` server notice mask. This is the only subsystem with a default log file. | + +## Configuration + +The true power of the logging subsystem comes from its extremely +flexible configuration. The default server facility can be +configured, as can the facility for each individual subsystem +described above. Moreover, administrators can configure the server to +log to specific files, send selected log messages to operators +subscribed to any server notice mask, and even change the default log +level for each subsystem. + +The logging subsystem has a set of tables mapping names to the +numerical values used internally. Subsystems, levels, syslog +facilities, and server notice masks are all configured using strings. +These tables even include special strings, such as "DEFAULT" and +"NONE." + +### Default syslog facility + +The IRC server has a default facility that it uses when sending log +messages to syslog. The default facility may be overridden for each +individual subsystem, but the default itself can be changed with an +appropriate Feature entry in the configuration file. The facility +normally defaults to "USER," but may be configured to be any of AUTH, +CRON, DAEMON, LOCAL0 through LOCAL7, LPR, MAIL, NEWS, USER, or UUCP. +Some systems also have the AUTHPRIV facility. To configure this +default, add a Feature line to the configuration file: + +``` +"LOG" = ""; +``` + +### Log files + +Each subsystem may be configured to send its log messages to any +single log file: + +``` +"LOG" = "" "FILE" ""; +``` + +`` is one of the subsystem names described above, and +`` is a file name for the log file. The file name may be +relative to the server's data directory ("DPATH"), or it may be an +absolute path name. Note that if you're using chroot, absolute path +names are relative to the server's root directory. + +### Logging to syslog + +By default, except for the CONFIG subsystem, no logs are sent to +syslog. This can be overridden with: + +``` +"LOG" = "" "FACILITY" ""; +``` + +`` must be one of the facility strings mentioned under +"Default syslog facility." The facility string may also be "NONE," to +turn off syslog for that subsystem, and "DEFAULT," to use the server's +default facility. Please don't confuse a DEFAULT facility with the +default for a particular subsystem; only the CONFIG subsystem defaults +to DEFAULT, whereas all the rest default to NONE. + +### Logging via server notices + +Log messages can be sent to online IRC operators. Many subsystems +actually default to this behavior, in fact. For security, log +messages containing IP addresses or other extremely sensitive data +will never be sent via server notices, but all others can be sent to a +specific server notice mask. (For more information about server +notice masks, please see `doc/snomask.md`.) The available mask names +are OLDSNO, SERVKILL, OPERKILL, HACK2, HACK3, UNAUTH, TCPCOMMON, +TOOMANY, HACK4, GLINE, NETWORK, IPMISMATCH, THROTTLE, OLDREALOP, +CONNEXIT, DEBUG, and AUTH. The special mask name "NONE" inhibits +sending of server notices for a particular subsystem: + +``` +"LOG" = "" "SNOMASK" ""; +``` + +### Setting the minimum logging level + +The minimum log level for a particular subsystem may be set with: + +``` +"LOG" = "" "LEVEL" ""; +``` + +`` is one of the level names described above. diff --git a/doc/readme.netconf b/doc/readme.netconf deleted file mode 100644 index 32b7d419..00000000 --- a/doc/readme.netconf +++ /dev/null @@ -1,149 +0,0 @@ -# Network Configuration (netconf) Feature - -## Overview -The `netconf` feature provides a dynamic, network-wide configuration system. It allows services (such as SASL authentication layers) to set, update, or delete configuration options that are instantly propagated to all servers in the network. This eliminates the need for manual updates to feature blocks or configuration files on every server when introducing new service-related settings that would need to be known by ircu. - -## Key Concepts -- **Network-wide Options:** Settings are stored in a central configuration list and propagated to all servers. -- **Dynamic Updates:** Options can be set, updated, or deleted at runtime without reloading configuration files. -- **Timestamps:** Each configuration entry is timestamped; only newer updates are accepted, preventing stale data from overwriting recent changes. -- **Callbacks:** Modules can register callbacks for configuration key prefixes (e.g., `sasl.`) to react to changes instantly. -- **Service Integration:** Especially useful for SASL and other service-related features, allowing them to advertise supported mechanisms and options network-wide. - -## How It Works -- **Setting a Configuration:** - - Services send a `CF` (CONFIG) message with a key, value, and timestamp. - - If the value is empty, the key is deleted (if the timestamp is newer). - - If the key exists and the timestamp is newer, the value is updated. - - Changes are propagated to all servers. -- **Registering Callbacks:** - - Modules can register a callback for a key prefix to be notified when relevant configuration changes occur. - -## Example Use Case: SASL -The SASL authentication service can dynamically advertise supported mechanisms to the entire network using netconf. For example, when the service starts or its capabilities change, it can send: - -``` -YY CF 1711200000 sasl.mechanisms :PLAIN,EXTERNAL,SCRAM-SHA-256 -``` - -This message sets the `sasl.mechanisms` key to the given value with the specified timestamp. All servers will update their configuration and propagate the change. To remove the key: - -``` -YY CF 1711201234 sasl.mechanisms -``` - -This deletes the key if the timestamp is newer than the previous value. - -**No static config changes are needed in ircd.conf; this is all dynamic and network-wide.** - -## API Summary -## Accessing Configuration Options in Code - -The ircu codebase uses an enum, `NetConf`, to represent each network configuration feature. These enums are used as keys to access configuration values in a type-safe and readable way. For example: - -```c -/** Network configuration options */ -enum NetConf { - NETCONF_SASL_SERVER, - NETCONF_SASL_MECHANISMS, - NETCONF_SASL_TIMEOUT, - NETCONF_LAST_NC -}; -``` - -To access a configuration value, use one of the following functions: - -- `int netconf_int(enum NetConf key);` — Get an integer config value -- `int netconf_bool(enum NetConf key);` — Get a boolean config value -- `const char *netconf_str(enum NetConf key);` — Get a string config value - -Example usage: - -```c -int timeout = netconf_int(NETCONF_SASL_TIMEOUT); -const char *mechs = netconf_str(NETCONF_SASL_MECHANISMS); -``` - -This approach ensures that features are accessed consistently and safely throughout the codebase. These are not modules, but configuration features/options. New features should be added as new enum values in `NetConf`. - -- `int config_set(const char *key, const char *value, time_t timestamp);` - - Set or update a configuration key/value with a timestamp. -- `const char *config_get(const char *key);` - - Retrieve the value for a configuration key. -- `void config_register_callback(const char *key_prefix, config_callback_f callback);` - - Register a callback for changes to keys with the given prefix. -- `void config_unregister_callback(const char *key_prefix);` - - Unregister a callback. -- `void config_burst(struct Client *cptr);` - - Send all current configuration entries to a newly connected server. -- `void config_stats(struct Client *sptr, const struct StatDesc *sd, char *param);` - - Show configuration entries using /STATS C. - -## Integration Example: Registering for SASL Changes - -Suppose you are writing a module that needs to react when the available SASL mechanisms change. You can register a callback for the `sasl.` prefix: - -```c -static void sasl_mech_update(const char *key, const char *old_value, const char *new_value) { - printf("SASL config changed: %s: %s -> %s\n", key, old_value ? old_value : "(unset)", new_value ? new_value : "(deleted)"); - // React to new mechanisms, e.g., update internal state -} - -void module_init(void) { - config_register_callback("sasl.", sasl_mech_update); -} - -void module_exit(void) { - config_unregister_callback("sasl."); -} -``` - -Now, whenever any `sasl.*` key is set, updated, or deleted, your callback will be invoked. - -## Integration Example: Setting and Reading a Config Value - -To set a network-wide option from code (e.g., from a service or privileged module): - -```c -#include -time_t now = time(NULL); -config_set("sasl.mechanisms", "PLAIN,EXTERNAL", now); -``` - -To read the current value anywhere in the codebase: - -```c -const char *mechs = config_get("sasl.mechanisms"); -if (mechs) { - printf("Current SASL mechanisms: %s\n", mechs); -} -``` - -This pattern can be used for any feature that needs dynamic, network-wide configuration. - -## Example: Full CF Message Syntax - -``` -CF -``` - -- ``: UNIX time (seconds since epoch) -- ``: configuration key (e.g., `sasl.mechanisms`) -- ``: value to set (omit or leave empty to delete the key) - -Examples: - -``` -CF 1711200000 sasl.mechanisms PLAIN,EXTERNAL,SCRAM-SHA-256 -CF 1711201234 sasl.mechanisms -``` - -## Benefits -- Centralized, real-time configuration for the entire IRC network -- Reduces operational overhead and risk of configuration drift -- Enables rapid deployment of new service features - -## See Also -- `include/ircd_netconf.h` -- `ircd/ircd_netconf.c` -- `ircd/m_config.c` diff --git a/doc/readme.netconf.md b/doc/readme.netconf.md new file mode 100644 index 00000000..210d85cd --- /dev/null +++ b/doc/readme.netconf.md @@ -0,0 +1,181 @@ +# Network configuration (netconf) + +## Overview + +The netconf subsystem provides dynamic, network-wide configuration. +A service (or other server) can set, update, or delete options that are stored on every server and propagated over server links. +This avoids editing `ircd.conf` Feature blocks on each server for settings that must stay in sync network-wide (for example SASL and S-line / spamfilter). + +## Key concepts + +- **Network-wide store:** Key/value entries live in a linked list on each server and are burst to newly linked peers. +- **Dynamic updates:** Entries can change at runtime without reloading local configuration files. +- **Timestamps:** Each entry carries a UNIX timestamp; only a newer timestamp is accepted, so stale updates cannot overwrite fresher data. +- **Typed accessors:** Known keys are exposed through the `NetConf` enum and `netconf_int` / `netconf_bool` / `netconf_str`, with compiled-in defaults when unset. +- **Callbacks:** Built-in code can register a prefix callback (for example `sasl.`) to react when matching keys change. +- **Server-to-server only:** The `CONFIG` / `CF` command is handled on server links (`ms_config`); clients do not set netconf. + +## How it works + +Services send a `CONFIG` message (P10 token `CF`) with a timestamp, key, and optional value: + +- If the value is omitted or empty and the timestamp is newer, the key is deleted. +- If the key is new, or exists with an older timestamp, the value is created or updated. +- Accepted changes are forwarded to other servers and may generate operator notices (`SNO_NETWORK`). +- On server burst, `config_burst()` sends all current entries to the new peer. + +## Known keys + +These keys are defined in `include/ircd_netconf.h` / `ircd/ircd_netconf.c`. +Arbitrary keys may still be stored via `CF`, but only the keys below have typed accessors and defaults. + +### SASL + +| Key | Type | Default | Purpose | +| --- | --- | --- | --- | +| `sasl.server` | string | empty | Nick/name of the SASL service server | +| `sasl.mechanisms` | string | empty | Comma-separated mechanism list (also used as the IRCv3 `sasl` CAP value) | +| `sasl.timeout` | integer | `30` | SASL session timeout in seconds | + +`ircd/sasl.c` registers a `sasl.` callback on init. +When `sasl.mechanisms` changes it updates the CAP value; capability availability is recomputed when SASL-related keys change. + +### S-line (spamfilter) + +| Key | Type | Default | Purpose | +| --- | --- | --- | --- | +| `sline.server` | string | empty | Nick/name of the spamfilter service server | +| `sline.hold_timeout` | integer | `60` | Hold-entry lifetime in seconds | +| `sline.hold_timeout_block` | boolean | `true` | If true, expire held matches as blocks; see `ircd/sline.c` | + +S-lines also require the `DISABLE_SLINES` feature to be `FALSE`. +Boolean netconf values accept `true` / `1` / `yes` (case-insensitive comparison as implemented). + +## CF message syntax + +Long name `CONFIG`, P10 token `CF`: + +``` +CF [:] +``` + +- ``: UNIX time (seconds since epoch) +- ``: configuration key (for example `sasl.mechanisms`) +- ``: value to set; omit (or send empty) to delete when the timestamp is newer + +Examples (P10 with source numnick): + +``` +YY CF 1711200000 sasl.mechanisms :PLAIN,EXTERNAL,SCRAM-SHA-256 +YY CF 1711201234 sasl.mechanisms +YY CF 1711202000 sline.server :spamfilter.example.net +YY CF 1711202001 sline.hold_timeout :120 +YY CF 1711202002 sline.hold_timeout_block :yes +``` + +No matching `ircd.conf` Feature entries are required for these keys; they are purely network state. + +## Operator visibility + +Oper `/STATS C`, `/STATS config`, or `/STATS netconf` lists current entries as timestamp, key, and value. +Access is gated like other oper stats (`HIS_STATS_C`). +This is distinct from `/STATS c` (connect blocks); both letters are case-sensitive in stats. + +## Accessing options in code + +```c +enum NetConf { + NETCONF_SASL_SERVER, + NETCONF_SASL_MECHANISMS, + NETCONF_SASL_TIMEOUT, + NETCONF_SLINE_SERVER, + NETCONF_SLINE_HOLD_TIMEOUT, + NETCONF_SLINE_HOLD_TIMEOUT_BLOCK, + NETCONF_LAST_NC +}; +``` + +Typed getters (use the default from `netconf_descs` when the key is unset): + +- `int netconf_int(enum NetConf key);` +- `int netconf_bool(enum NetConf key);` +- `const char *netconf_str(enum NetConf key);` + +```c +int timeout = netconf_int(NETCONF_SASL_TIMEOUT); +const char *mechs = netconf_str(NETCONF_SASL_MECHANISMS); +``` + +Add new well-known options by extending the `NetConf` enum and the `netconf_descs[]` table in `ircd/ircd_netconf.c`. + +## API summary + +- `int config_set(const char *key, const char *value, time_t timestamp);` + - Create, update, or delete a key. + - Returns `CONFIG_REJECTED` (-1), `CONFIG_CREATED` (0), `CONFIG_TIMESTAMP` (1), `CONFIG_CHANGED` (2), or `CONFIG_DELETED` (3). +- `const char *config_get(const char *key);` + - Raw value, or `NULL` if unset (no default applied). +- `void config_register_callback(const char *key_prefix, config_callback_f callback);` + - Invoke `callback(key, old_value, new_value)` when a matching key changes (`new_value` is `NULL` on delete). +- `void config_unregister_callback(const char *key_prefix);` +- `void config_burst(struct Client *cptr);` + - Send all entries to a linking server. +- `void config_stats(struct Client *sptr, const struct StatDesc *sd, char *param);` + - Implement `/STATS C` / `config` / `netconf`. + +## Callback example (in-tree) + +`sasl_init()` registers for the `sasl.` prefix: + +```c +static void sasl_config_callback(const char *key, const char *old_value, + const char *new_value) +{ + if (ircd_strcmp(key, "sasl.mechanisms") == 0) + cap_set_value(E_CAP_SASL, new_value); + sasl_check_capability(); +} + +void sasl_init(void) +{ + config_register_callback("sasl.", sasl_config_callback); +} +``` + +## Setting and reading values + +From privileged server-side code: + +```c +#include + +time_t now = time(NULL); +config_set("sasl.mechanisms", "PLAIN,EXTERNAL", now); +``` + +Reading without defaults: + +```c +const char *mechs = config_get("sasl.mechanisms"); +if (mechs) + /* use mechs */; +``` + +Prefer `netconf_str` / `netconf_int` / `netconf_bool` for known keys so defaults apply. + +## Benefits + +- One place to push service settings to the whole network +- Less config drift between servers +- Timestamp ordering avoids clobbering newer state during netsplits/rejoins + +## See also + +- `include/ircd_netconf.h` +- `ircd/ircd_netconf.c` +- `ircd/m_config.c` +- `ircd/sasl.c` +- `ircd/sline.c` +- `doc/readme.sasl.md` +- `doc/readme.sline.md` +- `doc/readme.features.md` (`DISABLE_SLINES`, `HIS_STATS_C`, `CAP_SASL`) diff --git a/doc/readme.sasl.md b/doc/readme.sasl.md new file mode 100644 index 00000000..0dd056cb --- /dev/null +++ b/doc/readme.sasl.md @@ -0,0 +1,113 @@ +# SASL authentication + +## Overview + +ircu implements IRCv3 SASL by advertising the `sasl` capability and handling client `AUTHENTICATE` messages. +Authentication itself is performed by an external login / services server over `XQUERY` / `XREPLY` (routing prefix `sasl:`). +ircu tracks per-client sessions (cookie, timeout) and applies success/failure replies to the client. + +SASL can run during registration (before the client is a user) or after registration. +During registration, a successful `OK` reply can set account information on the auth request; when registration finishes the client is introduced with umode `+r` and that account. +After registration, account assignment is expected via the usual account (`AC`) path (or the client may already have been introduced with `+r` / account from earlier SASL); ircu still sends `RPL_LOGGEDIN` / `RPL_SASLSUCCESS` on success. + +## Enabling SASL + +SASL is offered to clients only when **all** of the following hold: + +1. Feature `CAP_SASL` is `TRUE` (default). +2. Netconf `sasl.server` is set and that server is currently linked. +3. Netconf `sasl.mechanisms` is non-empty. + +`sasl_available()` encodes (2) and (3). +The CAP starts as unavailable (`CAPFL_UNAVAILABLE`) and is toggled with `sasl_check_capability()` on netconf changes and after netjoins/netsplits (`END_OF_BURST` / server exit). + +When `sasl.mechanisms` changes, its value is also set as the IRCv3 CAP value for `sasl` (mechanism list advertised to CAP LS 302 clients). + +Related netconf keys (see `doc/readme.netconf.md`): + +| Key | Type | Default | Purpose | +| --- | --- | --- | --- | +| `sasl.server` | string | empty | Login / SASL service server name (must be linked) | +| `sasl.mechanisms` | string | empty | Comma-separated mechanism names (also CAP value) | +| `sasl.timeout` | integer | `30` | Seconds before an in-progress session fails | + +## Client flow (`AUTHENTICATE`) + +Command name `AUTHENTICATE` (same long name and token). +Handled for local clients that have negotiated `CAP_SASL` (`m_sasl`). + +| Client sends | Behaviour | +| --- | --- | +| `AUTHENTICATE ` | Start a session if none is active; mechanism must appear in `sasl.mechanisms` | +| `AUTHENTICATE ` | Continuation while a session cookie is set (base64 / `+` as usual for IRCv3) | +| `AUTHENTICATE *` | Abort; clears session and sends `ERR_SASLABORTED` (906) | + +Constraints and errors: + +- Without `CAP_SASL`, `AUTHENTICATE` is ignored (no reply). +- Already authenticated (`FLAG_SASL` or `FLAG_ACCOUNT`) → `ERR_SASLALREADY` (907). +- SASL unavailable / service disconnected → `ERR_SASLFAIL` (904) with a disconnect notice. +- Parameter longer than 400 characters → `ERR_SASLTOOLONG` (905). +- Unknown mechanism → `RPL_SASLMECHS` (908) listing `sasl.mechanisms`. + +On a successful start, ircu assigns a non-zero session cookie, stores it in a cookie→client hash, and starts a relative timeout of `sasl.timeout` seconds. +Timeout sends `ERR_SASLFAIL` (“Authentication timed out”) and clears the session. + +## Service protocol (`XQUERY` / `XREPLY`) + +General extension-query syntax is documented in `doc/readme.xquery`. +SASL uses routing tokens of the form `sasl:`. + +### Initial query (unregistered client) + +``` +XQ sasl: :SASL +``` + +`` is the client TLS fingerprint, or `_` if none. + +### Initial query (already registered user) + +``` +XQ sasl: :SASL +``` + +### Continuation + +``` +XQ sasl: :SASL +``` + +### Replies (to the originating server) + +``` +XR sasl: :SASL +XR sasl: :OK [[:[:]]] +XR sasl: :NO +``` + +| Reply | Effect | +| --- | --- | +| `SASL …` | Forwarded to the client as `AUTHENTICATE <…>` (text after the `SASL ` prefix) | +| `OK` / `OK ` | Success: stop timeout, clear session, set `FLAG_SASL`, send `RPL_SASLSUCCESS` (903). For unregistered clients, `account_info` is parsed as `account[:id[:flags]]` via `auth_set_account`, and the user is later introduced with `+r` and that account. For registered clients, send `RPL_LOGGEDIN` (900); services should set or confirm account with `AC` if needed. Bare `OK` with no account string does not set account fields. | +| `NO ` | Failure: `ERR_SASLFAIL` with ``, clear session | + +## Operator visibility + +`/STATS S` or `/STATS sasl` (gated by `HIS_STATS_S`) reports whether SASL is available, the configured server, mechanisms, timeout, and success/failure counters. + +## Implementation notes + +- Cookie allocation uses a local ticker (skips 0); sessions are hashed for `XREPLY` lookup. +- Disconnect clears any outstanding SASL session for the client. +- `CAP_SASL` only gates advertising/requesting the capability; netconf still controls real availability. +- Client-facing SASL numerics are in the 900–908 range (`include/numeric.h`). + +## See also + +- `include/sasl.h`, `ircd/sasl.c`, `ircd/m_sasl.c`, `ircd/m_xreply.c` +- `doc/readme.netconf.md` (`sasl.*` keys) +- `doc/readme.features.md` (`CAP_SASL`, `HIS_STATS_S`) +- `doc/readme.xquery` +- IRCv3 SASL specs: https://ircv3.net/specs/extensions/sasl-3.1 and https://ircv3.net/specs/extensions/sasl-3.2 +- `doc/readme.cap.md` (capability negotiation) diff --git a/doc/readme.sline.md b/doc/readme.sline.md new file mode 100644 index 00000000..8a88a413 --- /dev/null +++ b/doc/readme.sline.md @@ -0,0 +1,140 @@ +# S-lines (spamfilter) + +## Overview + +S-lines are network-wide POSIX extended regular expressions used for spam filtering. +A services server publishes patterns with the `SLINE` / `SL` command; every linked ircu stores them and, when a local user’s message matches, can hold delivery while it asks a configured spamfilter service for a decision via `XQUERY` / `XREPLY`. + +Unlike G-lines, S-lines do not disconnect clients by themselves. +Private and channel traffic is held for approval; `PART` and `QUIT` reasons that match are suppressed instead. + +## Enabling S-lines + +S-line checking runs only when **both** are true: + +1. Feature `DISABLE_SLINES` is `FALSE` (the default). +2. Netconf key `sline.server` is set to the name of a linked spamfilter / services server. + +If either condition fails, matching is skipped. +If a pattern matches but `sline.server` is not currently linked, private/channel paths **fail open** and deliver the message instead of holding it for the full timeout. + +Related netconf keys (see `doc/readme.netconf.md`): + +| Key | Type | Default | Purpose | +| --- | --- | --- | --- | +| `sline.server` | string | empty | Spamfilter server name (must be linked) | +| `sline.hold_timeout` | integer | `60` | Seconds to wait for an `XREPLY` before timeout | +| `sline.hold_timeout_block` | boolean | `true` | On timeout: block (`true`) or release (`false`) | + +## SLINE command (server-to-server) + +Long name `SLINE`, P10 token `SL`. +Handled only from servers (`ms_sline`); there is no client `SLINE` command. + +``` +SL : +``` + +| Field | Meaning | +| --- | --- | +| `` | `+` active, `-` inactive | +| `` | UNIX timestamp of this change (newer wins; `0` becomes “now”) | +| `` | UNIX expiry time, or `0` for never | +| `` | One or more type letters (see below) | +| `` | POSIX extended regex (`REG_EXTENDED`); max length `SLINELEN` (470) | + +Examples: + +``` +YY SL + 1711200000 0 PC :viagra +YY SL + 1711200100 1711286400 A :(?i)free\s+crypto +YY SL - 1711200200 0 A :oldpattern +``` + +Identical patterns are updated in place when `lastmod` is newer (state, types, and/or expire). +Stale or no-op updates are ignored. +On server burst, all known S-lines are sent with `sline_burst()`. + +Invalid regexes are still stored and burst, but marked invalid (`I` in notices/stats) and never match. + +## Message type flags + +| Letter | Flag | Applies to | +| --- | --- | --- | +| `A` | all | Private, channel, part, and quit (overrides other letters) | +| `P` | private | `PRIVMSG` / `NOTICE` to users (and related private paths) | +| `C` | channel | Channel `PRIVMSG` / `NOTICE`, `WALLCHOPS`, `WALLVOICES`, channel `TAGMSG` | +| `L` | part | `PART` reasons | +| `Q` | quit | `QUIT` reasons | + +Operators (`IsAnOper`) are exempt from all S-line checks. + +## Matching behaviour + +### Private and channel messages + +Checked with `sline_check_privmsg` / `sline_check_chanmsg` on the local server that would deliver the message. + +On match: + +1. The message is placed on a **hold queue** with a unique token (client gets `FLAG_SPAMHOLD` while referenced). +2. An `XQUERY` is sent to `sline.server`: + +``` +XQ spam: : : +``` + +`` is a user (private) or channel (channel). +`` is space-separated regex capture groups, or the full match if there were no groups (up to 15 capturing groups; see `SLINE_MAX_CAPTURES`). + +3. The spamfilter answers with `XREPLY` using the same routing token: + +``` +XR spam: :YES +XR spam: :NO +``` + +- `YES` — deliver the held message (preserving `PRIVMSG` vs `NOTICE` / wall* semantics, including `echo-message` where applicable). +- `NO` — drop it and send a normal-looking error to the sender (`ERR_NOSUCHNICK` for private, `ERR_CANNOTSENDTOCHAN` for channel). + +### Hold timeout + +A periodic timer (every 10 seconds) expires holds older than `sline.hold_timeout`. + +- If `sline.hold_timeout_block` is true (default): block like `NO`. +- If false: release like `YES`. + +Disconnecting clients and destroyed channels clean up their hold-queue entries. + +### PART and QUIT + +These use a boolean match only (`sline_check_pattern_bool`); there is no hold queue or `XQUERY`. + +- Matching `PART` reasons are suppressed (treated like a banned/nopartmsgs part). +- Matching `QUIT` reasons cause a generic “Signed off” exit when the user is on channels that would show the quit text. + +## Operator visibility + +`/STATS s` or `/STATS slines` (gated by `HIS_STATS_s`) lists active S-lines (`RPL_STATSSLINE` / 240): lastmod, expire, hit count, type string, and pattern. + +It also reports whether S-lines are enabled, the configured spamfilter server, hold timeout settings, and counters (hits, held, released, blocked, XREPLY accepted/rejected, timeouts). + +Memory use appears under server meminfo reporting (`sline_send_meminfo`). + +Oper notices for add/modify use `SNO_GLINE`. + +## Implementation notes + +- Patterns are compiled once with `regcomp(..., REG_EXTENDED)`. +- Only **active** and **valid** lines for the relevant message type are considered; expired lines are freed when encountered. +- Hold-queue and S-line lists are local state derived from S2S traffic; there is no `ircd.conf` S-line block. +- Extension query details: `doc/readme.xquery`. + +## See also + +- `include/sline.h`, `ircd/sline.c`, `ircd/m_sline.c`, `ircd/m_xreply.c` +- `doc/readme.netconf.md` (`sline.*` keys) +- `doc/readme.features.md` (`DISABLE_SLINES`, `HIS_STATS_s`) +- `doc/readme.xquery` +- `doc/readme.sasl.md` (uses the same `XQUERY` / `XREPLY` mechanism with `sasl:`) +- `doc/readme.gline` (different mechanism: user bans) diff --git a/doc/readme.who b/doc/readme.who deleted file mode 100644 index f0b5c4d3..00000000 --- a/doc/readme.who +++ /dev/null @@ -1,283 +0,0 @@ -WHO documentation, updated on 02 Jan 1999. - -Since ircu2.10.02 the WHO command had been changed from what described in -RFC1459, while still keeping backward compatibility, actually it has been -changed again in u2.10.05 so that since this release the format of the who -query is now: - -[:source] WHO [ []] - - is optional, if mask2 is present it's used for matching and mask1 is -ignored, otherwise mask1 is used for matching, since mask2 is the last -parameter it *can* contain a space and this can help when trying to match a -"realname". - -When matching IP numbers the can be in 3 forms: - -- The old and well known IRC masks using * and ? as wanted -- The IPmask form a.b.c.d/e.f.g.h as used in most firewalls and - system configurations, where what is before the / are the bits we expect - in the IP number and what is after the / is the "filter mask" telling wich - bits whould be considered and wich should be ignored. -- The IPmask form a.b.c.d/bitcount where bitcount is an integer between 0 - and 31 (inclusive), the matching will be for the IPs whose first - "bitcount" bits are equal to those in a.b.c.d - -Note that: -. The bitcount must be between 0 and 31, 32 is NOT good (and - makes no sense to use it... just match against the static IP a.b.c.d) -. The missing pieces of both the bitmask and the ipnumber in the forms - ipnumber/bitmask and ipnumber/bitcount default to zero from right to left, - this is NOT what inet_aton and most tools do but makes more sense here - IMO, in example /who 194.243/16 is taken as /who 194.243.0.0/255.255.0.0 - (inet_aton whould take 194.243 as 194.0.0.243). -. For the above reason and specified validity limits 1.2.3.4/31 becomes - 1.2.3.4/255.255.255.254 while 1.2.3.4/32 becomes 1.2.3.4/32.0.0.0 :) - -For all the other fields th match happens as has always been, i.e. it's only -considered the IRC mask with * and ? (that is: don't expect to catch an user -with "realname" = "1.2.3.4" when doing "/who 1.2/16 h" :) - -For both the masks and the options (and thus for all flags) case is NOT -significative (so "/who o" is exactly the same as "/who O". - -The "options" part can be as follows: - - [][%[[,]]] - -in which: - - : can be a sequence of field matching flags, use mode matching flags - and special purpose flags - - Field matching flags, when one of these is specified the field in - question is matched against the mask, otherwise it's not matched. - - n Nick (in nick!user@host) - u Username (in nick!user@host) - h Hostname (in nick!user@host) - i Numeric IP (the unresolved host) - s Servername (the canonic name of the server the guy is on) - r Info text (formerly "Realname") - a Account name - - If no field-matching flags are specified they default to what old servers - used to do: nuhsr (= everything except the numeric IP) - - User mode matching flags (specifying one of these means that only clients - with that umode are considered, what is not specified is always matched): - - d Join-delayed channel members - o Irc operator - [In the future more flags will be supported, basically all - usermodes plus the +/- specificators to revert the filtering] - - Special purpose flags: - - x If this is specified the extended visibility of information for opers - is applied, what this means depends on the fact that you are local or - global operator and on how the admin configured the server (global - and eventually local irc opers might be allowed with this flag to see - +i local users, to see all +i users, to see users into +p and/or +s - channels, and so on). Using the 'x' flag while not being an irc - operator is meaningless (it will be ignored), using it while oper'd - means that the query is almost certainly logged and the admin might - (rightfully) ask you an explanation on why you did. - - The rest, what follows the %, that is [%[fields[,]]], is as it - has always been since the first who.patch, the part specifies - wich fields to include in the output as: - - c : Include (first) channel name - d : Include "distance" in hops (hopcount) - f : Include flags (all of them) - h : Include hostname - i : Include IP - l : Include idle time (0 for remote users) [2.10.11+] - n : Include nick - r : Include real name - s : Include server name - t : Include the querytype in the reply - u : Include userID with eventual ~ - a : Include account name - o : Include oplevel (shows 999 to users without ops in the channel) - -And the , final option can be used to specify what you want the -server to say in the querytype field of the output, useful to filter the -output in scripts that do a kind of "on 354 ..." - -If no %fields are specified the reply is _exactly_ the same as has always -been, numeric 352, same fields, same order. - -If one or more %fields are specified the reply uses a new numeric, since an -out-of-standard 352 crashes EPIC and confuses several other clients. I used -354. - -:"source" 354 "target" ["querytype"] ["channel"] ["user"] - ["IP"] ["host"] ["server"] ["nick"] - ["flags"] ["hops"] ["idle"] ["account"] - ["oplevel"] [:"realname"] - -Where only the fields specified in the %fields options are present. - -"querytype" is the same value passed in the /who command, it is provided to -simplify scripting, in example one could pass a certain value in the query -and have that value "signal" back what is to be done with those replies. - -The number of lines in the reply is still limited to avoid self-flooding and -sooner or later another limitation will be added: you will be forced to do -no more than one /who query every 'n' seconds where 'n' depends on the -number of fields you actually match (the field-match flags specified before -% in the option, defaulting to 6 if you don't specify an option at all), -infact matching against many fields as the default query does severely -affects the CPU usage of the server and is *much* better to specify with the -field-matching flags what you are looking for, in example when you are -looking for all french users a "/who *.fr h" is A LOT better than just "/who -*.fr" (and actually you want users that have the -_hostname_ matching *.fr, you wouldn't want to match a japanese user -that has the realname "ku fung-kay aj.fr" in example...) - -Note that: - -- An user doing a "/who whatever" or a "/who whatever o" - will not see any change (except for the anti-flood limit and sooner or - later the CPU usage limit) - -- An user doing a "/who #wasteland %n" will get just a list of nicks (lame, - very lame way of doing it :-) - -- An user doing a "/who 0 o%nuhs" will get a list of the opers with Nick, - userID, server and hostname like: - -:Amst* 354 Nemesi #wasteland nbakker pc73.a.sn.no Oslo*.org Niels - -- An user doing a "/who 0 o%tnuhs,166" will get a list of the opers - with Nick, userID, server and hostname like the above but with a - request type field of 166 like: - - :Amst* 354 Nemesi 166 #wasteland nbakker pc73.a.sn.no - Oslo-R.NO.EU.Undernet.org Niels - - So that he can have in example a script that does - on ^354 "% 166" display "There is an oper ..." - -- The client will have to sort/format the fields by itself, - the _order_ in which flags are passed is not significant, the fields in the - reply will always have the same order. - -- The maximum number of _lines_ reported as reply for a query - is 2048/(n+4) where 'n' is the number of flags "enabled" that is the - number of fields included in each reply. - - Actually: 1 field returned = maximum 409 replies - 2 fields returned = maximum 341 replies - 3 fields returned = maximum 292 replies - 4 fields returned = maximum 256 replies - 5 fields returned = maximum 227 replies - 6 fields returned = maximum 204 replies - 7 fields returned = maximum 186 replies (default query) - 8 fields returned = maximum 170 replies - 9 fields returned = maximum 157 replies - 10 fields returned = maximum 146 replies - - If the limit is reached before completing the query the reply is truncated - and a new numeric error is issued after the "End of WHO", anyway the "end - of" numeric is _always_ sent (otherwise some scripts and clients go - crazy). - -The actual "mask" to match can have one of the two following forms: - -- A comma-separated list of elements: in this case each element - is treated as a flat channel or nick name and is not matched to the other - elements. Nicks do count in the limit of output lines (they should not be - that many anyway), channels count if who asks the query is not on the - channel. (That is: a /who #channel gives unlimited output if you are in - there). - -- A _single_ mask: in this case (no commas, only one element) the mask is - first checked to be a full channel or nickname, then it is matched against - all relevant fiels as already known. These happens in different steps - with replicates-removal so that if one has (?) something like "#wasteland" - as "real name" or is on a channel named "#***MyChan***" it all works - nicely. - -Miscellaneous bug fixes / "undocumented feature" changes: - -- /who NickName did not show the user with nick = NickName when it was - invisible, even if the nick was given completely (without wildchars) now - it does, since one could always see him as /whois NickName. It does not - report him twice if he also has in example the userID == NickName and is - -i. - -- ":source WHO :The Black Hacker" did not report an user having "The Black - Hacker" as real name, now it does. Since this can only be done without the - flags/format specificator because that would become the "last parameter" - an escape has been provided: if you pass to m_who _3_ parameters the first - one will be ignored and the last one used for matching, like in example - ":source WHO foo %nuh :*Black Hacker*" where "foo" will not be used and - the match will happen on "*Black Hacker*". (It was passed through - clean_channelname() that prevented the mask from containing spaces and - such...) - -- When one user was umode -i he was shown or not depending on the - fact he was on a +p or +s channel... since we are doing a lookup on the - _user_ this makes no sense to me, example: - Neme1 : umode -i, on no channels, was SEEN with a /who 0 - Neme2 : umode -i, on channel #p with chmode +p, was NOT SEEN by /who 0 - Neme3 : umode -i, on channel #s with chmode +s, was NOT SEEN by /who 0 - - Now all users "-i" are matched with a "/who mask", the +i users instead - must be on a _common_ channel to be seen. - - Basically being on "one" +s|p channel "forced" a +i status while one might - want to be on #secret (mode +s) and have nobody know that he is in there - but on the other side stay -i so others can find him. Of course a +s|p - channel is never shown in the reply unless who asks the query is in there, - if no "visible" channels are available for a -i user he is shown on - "channel *". - -- When one user is +i is shown _only_ if there is a common channel, - the first common channel found is shown in the reply. - -- IRC operators with the "see_chan" privilege can /WHO #channel for - +s and +p channels even when they are not in the channel. - -- IRC operators with the "unlimit_query" privilege can get full results - for /WHO lists (until they get disconnected by max SendQ exceeded ;) - -- A /who a,c,b,d,e,f used to return as many ** END OF WHO as there - were elements in the list, since now the command is supposed to be - _efficient_ for /who nick1,nick2,nick3 .. I return a _single_ end - of query message. - -- /who did not work for a channel named in example #**StarWars** - now it does handle it properly (the mask was passed through - collapse() and then.. did not find that channel, fixed). - -- "/who #John" did not report an user having '#John' as "Real name", - now it does (and does NOT report him twice if he is ALSO on a - channel named #John, strange but true: this can happen). - -- "/who a,b,c,d" where a b c and d are channelnames/nicks now uses an hash - lookup and therefore is extremely efficient, if _only_ one field is - specified it is looked in all the fields; who really wants _only_ users on - a specific channel or a single nick (without looking for a match in the - other fields) can force the server to consider the parameter as a list - adding a comma somewhere, like: - - "/who #Italia," or "/who ,Nemesi" - - Or even better to avoid misbehaviour with other servers: - "/who #Italia %... #Italia," or "/who Nemesi %... Nemesi," - - This will make old servers act properly and new ones and should be the - recomended way for GUI based clients to get a channel's userlist and all - the infos they want about users on the channel. - -- If you use the new numeric, flags will contain all the information about - a user on a channel. @ for op'd, + for voiced, and ! for zombie. eg: - Isomer #coder-com H@+, where the old behavor of just displaying one of - them has been preserved for the old numeric. [2.10.11+] - -Regards, Andrea aka Nemesi - diff --git a/doc/readme.who.md b/doc/readme.who.md new file mode 100644 index 00000000..db10bd19 --- /dev/null +++ b/doc/readme.who.md @@ -0,0 +1,199 @@ +# WHO documentation + +Originally by Andrea "Nemesi" (02 Jan 1999); revised against the +current implementation in `ircd/m_who.c` and `ircd/whocmds.c`. + +Since ircu2.10.02 the WHO command has been extended from what RFC 1459 +describes, while keeping backward compatibility. The query format is: + +``` +WHO [ []] +``` + +`` is optional; if present it is used for matching and +`` is ignored. Since `` is the last parameter it *can* +contain a space, which helps when matching a real name, e.g. +`WHO foo %nr :*Black Hacker*`. + +Masks and options (and thus all flags) are case-insensitive. + +## Mask forms + +The mask can have one of two forms: + +- **A comma-separated list of elements**: each element is treated as a + flat channel or nick name and is not matched against the other + fields. Nicks count toward the output-line limit; channels count + only if the asker is not on the channel (a `WHO #channel` gives + unlimited output if you are in there). To force list treatment for + a single element, add a comma: `WHO #Italia,` or `WHO ,Nemesi`. + This is the recommended way for clients to fetch a channel's user + list. + +- **A single mask**: the mask is first checked as a full channel or + nick name, then matched against all selected fields, with duplicate + removal — a user is reported once even if several fields match. + +### IP masks + +When matching IP addresses (the `i` match flag), the mask can be: + +- An ordinary IRC wildcard mask using `*` and `?`. +- CIDR notation `a.b.c.d/bitcount`, with bitcount from 0 to 32. + Missing octets default to zero from the right: `194.243/16` is + taken as `194.243.0.0/16`. +- A trailing-wildcard numeric form: `194.243.*` is equivalent to + `194.243.0.0/16`. +- An IPv6 address, optionally with `/bitcount` (0 to 128). + +CIDR/numeric forms apply only to the IP field; every other field is +matched with the ordinary `*`/`?` wildcard rules (don't expect to +catch a user whose real name is "1.2.3.4" with `WHO 1.2/16 h`). + +*Historical note:* the netmask form `a.b.c.d/e.f.g.h` accepted by very +old servers is no longer parsed, and `/32` (an exact address) is now +valid. + +## Options + +The options parameter has the form: + +``` +[][%[][,]] +``` + +### Field-matching flags + +When one of these is specified the field in question is matched +against the mask; otherwise it is not matched. + +| Flag | Field matched | +|------|---------------| +| `n` | Nick (in nick!user@host) | +| `u` | Username (in nick!user@host) | +| `h` | Hostname (in nick!user@host) | +| `i` | Numeric IP (the unresolved host) | +| `s` | Server name (the canonical name of the server the user is on) | +| `r` | Info text (formerly "real name") | +| `a` | Account name | + +If no field-matching flags are specified, the default is `nuhs` +(nick, username, hostname, server). Note that the info text is *not* +matched by default — ask for it explicitly with `r`. + +With the `HIS_WHO_SERVERNAME` feature enabled (the default), non-opers +cannot match on the server field; `s` is silently dropped for them. + +For users with hidden hosts, non-opers match only the visible host and +username and can never match the numeric IP; opers additionally match +against the real host and real username. + +### Selection flags + +Specifying one of these restricts which clients are considered: + +| Flag | Effect | +|------|--------| +| `o` | Only IRC operators. Only opers whose status is visible (the `display` privilege) are listed. | +| `d` | Also show join-delayed channel members (channel mode `+D`). | + +### Special purpose flags + +| Flag | Effect | +|------|--------| +| `x` | Extended visibility for opers: see invisible (+i) users everywhere and, with the `see_chan` privilege, look into secret (+s) and private (+p) channels. Requires oper status *and* the `whox` privilege; otherwise it is silently ignored. Every use is written to the WHO log subsystem (see `doc/readme.log.md`). | + +### Output fields + +The `%` part specifies which fields to include in the output: + +| Field | Included | +|-------|----------| +| `c` | (First visible) channel name | +| `d` | "Distance" in hops (hop count) | +| `f` | Flags (all of them) | +| `h` | Hostname | +| `i` | IP | +| `l` | Idle time | +| `n` | Nick | +| `r` | Real name | +| `s` | Server name | +| `t` | The querytype in the reply | +| `u` | Username with eventual ~ | +| `a` | Account name (`0` if not authed) | +| `o` | Oplevel (`n/a` for members without ops; the real level is shown only to opers and to chanops of the channel, `999` to everyone else) | + +The `,` option (up to 3 digits) is echoed in the querytype +field of the output, useful for filtering replies in scripts. + +If no `%fields` are specified, the reply is exactly the traditional +numeric 352, same fields, same order. If one or more `%fields` are +specified the reply uses numeric 354 (since an out-of-standard 352 +confuses many clients), with only the requested fields present, always +in this order: + +``` +:server 354 target [querytype] [channel] [user] [IP] [host] [server] + [nick] [flags] [hops] [idle] [account] [oplevel] + [:realname] +``` + +The order in which the field letters are given is not significant; the +client has to sort/format the fields by itself. + +In the 354 reply the flags field carries the full channel-membership +state: `@` opped, `+` voiced, `!` zombie, `<` join-delayed (the 352 +reply keeps the old behavior of showing at most one of them). + +### HIS restrictions on output + +With the (default-enabled) HIS features, non-opers see censored +values: `HIS_WHO_SERVERNAME` replaces the server name with the +network's HIS server name and zeroes the idle field for other users; +`HIS_WHO_HOPCOUNT` reports hop count `0` for yourself and a flat `3` +for everyone else. Idle time is in any case only known for users +local to the answering server, and umode `+I` (hide idle) zeroes it +for everyone but the user themself and opers. + +## Visibility rules + +- Users who are `-i` (not invisible) are matched by any `WHO mask`. + Being on a secret or private channel does not hide a `-i` user + from a mask query, but such channels are never shown as their + channel; if no visible channel exists, `*` is shown instead. +- Users who are `+i` are shown only if they share a channel with the + asker; the first common channel found is shown. +- A full nick given as the mask finds the user even if invisible + (just as WHOIS would). +- `WHO #channel` on a secret/private channel works only for members — + or for opers with the `see_chan` privilege using the `x` flag. + +## Output limits + +The maximum number of reply lines for a mask query is `2048/(n+4)`, +where `n` is the number of fields included in each reply (7 for the +default 352 query): + +| Fields returned | Maximum replies | +|-----------------|-----------------| +| 1 | 409 | +| 2 | 341 | +| 3 | 292 | +| 4 | 256 | +| 5 | 227 | +| 6 | 204 | +| 7 | 186 (default query) | +| 8 | 170 | +| 9 | 157 | +| 10 | 146 | + +If the limit is reached the reply is truncated and an error numeric is +sent after the "End of WHO" — the "End of WHO" numeric is *always* +sent. A single "End of WHO" is returned even for a comma-separated +list. Opers with the `unlimit_query` privilege get full results +(until they get disconnected by max SendQ exceeded). + +Matching against many fields is CPU-expensive, and the default query +matches four of them. When looking for all French users, +`WHO *.fr h` is a lot better than `WHO *.fr` — and it is also what +you actually mean. diff --git a/doc/readme.xquery b/doc/readme.xquery deleted file mode 100644 index 8ab9658b..00000000 --- a/doc/readme.xquery +++ /dev/null @@ -1,96 +0,0 @@ -OVERVIEW -======== - -The extension query mechanism provides a means by which servers may -send queries to other servers and receive replies. Obviously, -ordinary ircu servers have no need of this mechanism, but it allows -pseudo-server services to communicate with each other. Additionally, -extensions have been made to the iauth protocol (see readme.iauth) to -allow iauth instances to send and receive extension queries. This -could be used, for instance, to submit client information for -immediate proxy scanning by a centralized service, or to query a -centralized database for log-in parameters. - -DETAILED DESCRIPTION -==================== - -The extension query mechanism consists of a pair of commands, the -XQUERY command (token XQ) and the XREPLY command (token XR). Servers -and IRC operators may send an XQUERY, naming a target service, an -opaque "routing" token, and the query; the target service is expected -to reply with an XREPLY, which will include the routing token from the -query and the service's reply to the query. - -The query syntax is: - - XQ : - -where is the target service's numeric nick, is the -opaque "routing" token, and is the query for the service to -act upon. IRC operators may also issue queries, using the XQUERY -command with the same parameters, with permitted to be a -server name mask; this is largely intended for debugging purposes. -Ordinary users cannot issue XQUERY commands, in order to encourage use -of the regular PRIVMSG and NOTICE commands. - -The reply syntax is: - - XR : - -where is the origin of the original query, is the -opaque "routing" token from the query, and is the service's -reply to the query. This command can only be issued by servers. - -USE WITH IAUTH -============== - -Three message extensions have been made to the iauth protocol. An -iauth instance can issue an XQUERY through the use of the "X" client -message with the following syntax: - - X : - -If is not presently linked to the network, ircu will -respond with an "x" server message, having the following syntax: - - x :Server not online - -If, on the other hand, names a valid, on-line server, -ircu will prepend "iauth:" to the "routing" token and forward the -query to that server. If an XREPLY is received from the service, ircu -will strip off the "iauth:" prefix on the "routing" token and send the -reply to the iauth instance with the "X" server message: - - X : - -Having the "iauth:" prefix on the "routing" token enables future ircu -extensions which wish to use the extension query mechanism to be -differentiated from extension queries originated from iauth. - -RATIONALE -========= - -The extension query mechanism was originated as part of an effort to -establish a reliable login-on-connect system for Undernet. Previous -attempts at such a system required out-of-band parallel connections, -and could possibly result in a compromise of hidden IPs (such as the -IP of X's database server). Further, without extensive extensions to -GNUWorld, certain login restrictions--such as the maximum logged-in -client count--could not be reliably enforced. By providing an in-band -signalling mechanism that iauth can make direct use of, these problems -are eliminated; the only remaining problem is what to do if iauth is -unable to communicate with the login service, which can be solved -through policy decisions and timeouts implemented within the iauth -instance. - -The rationale for the opaque "routing" token is to provide pairing -between replies and queries. The lack of such pairing is one of the -shortcomings of the IRC protocol, as specified in RFC 1459; only one -Undernet extension has attempted to provide such a pairing--a -little-used extension to the /WHO command. In an iauth context, such -pairing is critical; otherwise, iauth could potentially apply a reply -to the wrong client. Although the pairing could be part of the query, -it makes sense to make it part of the base protocol message, making it -explicit. This also allows ircu to add routing data to the token, -making it possible for more extensions than just iauth to make use of -extension queries. diff --git a/doc/readme.xquery.md b/doc/readme.xquery.md new file mode 100644 index 00000000..ab36c05b --- /dev/null +++ b/doc/readme.xquery.md @@ -0,0 +1,126 @@ +# Extension queries (XQUERY / XREPLY) + +## Overview + +The extension query mechanism provides a means by which servers may +send queries to other servers and receive replies. Obviously, +ordinary ircu servers have no need of this mechanism, but it allows +pseudo-server services to communicate with each other. Additionally, +extensions have been made to the iauth protocol (see +`readme.iauth.md`) to allow iauth instances to send and receive +extension queries. This could be used, for instance, to submit client +information for immediate proxy scanning by a centralized service, or +to query a centralized database for log-in parameters. + +## Detailed description + +The extension query mechanism consists of a pair of commands, the +XQUERY command (token `XQ`) and the XREPLY command (token `XR`). +Servers and IRC operators may send an XQUERY, naming a target service, +an opaque "routing" token, and the query; the target service is +expected to reply with an XREPLY, which will include the routing token +from the query and the service's reply to the query. + +The query syntax is: + +``` + XQ : +``` + +where `` is the target service's numeric nick, `` is +the opaque "routing" token, and `` is the query for the service +to act upon. IRC operators may also issue queries, using the XQUERY +command with the same parameters, with `` permitted to be a +server name mask; this is largely intended for debugging purposes. +Ordinary users cannot issue XQUERY commands, in order to encourage use +of the regular PRIVMSG and NOTICE commands. + +The reply syntax is: + +``` + XR : +``` + +where `` is the origin of the original query, `` is +the opaque "routing" token from the query, and `` is the +service's reply to the query. This command can only be issued by +servers. + +Both messages are forwarded hop by hop toward their target. XQUERY +and XREPLY lines never carry an IRCv3 `@time` tag on server links, +because services parse them positionally (see section 13 of +`doc/p10.md`). + +## Routing prefixes in use + +The routing token was designed so that ircu itself can prepend routing +data to it and dispatch replies to the right subsystem. This server +currently uses three such prefixes (see also section 11 of +`doc/p10.md`): + +| Routing prefix | Used by | +|----------------|---------| +| `iauth:` | IAuth extension queries; see below. | +| `sasl:` | Client SASL authentication relayed to the network's SASL server; see `readme.sasl.md`. | +| `spam:` | The spamfilter hold queue; see `readme.sline.md`. | + +A reply whose routing prefix is not recognized is logged and dropped. + +## Use with iauth + +Three message extensions have been made to the iauth protocol. An +iauth instance can issue an XQUERY through the use of the `X` client +message with the following syntax: + +``` +X : +``` + +If `` is not presently linked to the network, ircu will +respond with an `x` server message, having the following syntax: + +``` + x :Server not online +``` + +If, on the other hand, `` names a valid, on-line server, +ircu will prepend `iauth:` to the routing token and forward the query +to that server. If an XREPLY is received from the service, ircu will +strip off the `iauth:` prefix on the routing token and send the reply +to the iauth instance with the `X` server message: + +``` + X : +``` + +Having the `iauth:` prefix on the routing token enables other ircu +subsystems that use the extension query mechanism (such as SASL and +the spamfilter, above) to be differentiated from extension queries +originated by iauth. + +## Rationale + +The extension query mechanism was originated as part of an effort to +establish a reliable login-on-connect system for Undernet. Previous +attempts at such a system required out-of-band parallel connections, +and could possibly result in a compromise of hidden IPs (such as the +IP of X's database server). Further, without extensive extensions to +GNUWorld, certain login restrictions — such as the maximum logged-in +client count — could not be reliably enforced. By providing an +in-band signalling mechanism that iauth can make direct use of, these +problems are eliminated; the only remaining problem is what to do if +iauth is unable to communicate with the login service, which can be +solved through policy decisions and timeouts implemented within the +iauth instance. + +The rationale for the opaque "routing" token is to provide pairing +between replies and queries. The lack of such pairing is one of the +shortcomings of the IRC protocol, as specified in RFC 1459; only one +Undernet extension has attempted to provide such a pairing — a +little-used extension to the /WHO command. In an iauth context, such +pairing is critical; otherwise, iauth could potentially apply a reply +to the wrong client. Although the pairing could be part of the query, +it makes sense to make it part of the base protocol message, making it +explicit. This also allows ircu to add routing data to the token, +making it possible for more extensions than just iauth to make use of +extension queries — as the SASL and spamfilter subsystems now do. diff --git a/doc/snomask.html b/doc/snomask.html deleted file mode 100644 index 237a3bef..00000000 --- a/doc/snomask.html +++ /dev/null @@ -1,221 +0,0 @@ - - -SNOMASK - Server Notice Masks - - -
    - -

    SNOMASK - Server Notice Masks

    - -Written by Ghostwolf 18th June 1997
    -Modified with permission by loki 12th November 1997 -
    -


    - -
    -This document (hopefully) gives a brief explanation of the use of server -notice masks new to ircu2.10.00. This mask allows clients to specify which -types of server notices they will receive when usermode +s. The mask may -optionally be omitted, and reasonable defaults will be used by the server. -

    -Note: the descriptions here will be best understood by those with knowledge -of C syntax. We do not attempt to explain either this or hexadecimal values -in this document, and familiarity with these is assumed of the reader. -

    -Usage: - -/mode <nick> +s [+/-][mask] - -

    -

    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    Mask Hex valueDescription
    1SNO_OLDSNO0x1/* unsorted old messages */
    2SNO_SERVKILL0x2/* server kills (nick collisions) */
    4SNO_OPERKILL0x4/* oper kills */
    8SNO_HACK20x8/* desyncs */
    16SNO_HACK3 -0x10/* temporary desyncs */
    32SNO_UNAUTH0x20/* unauthorized connections */
    64SNO_TCPCOMMON0x40/* common TCP or socket errors */
    128SNO_TOOMANY0x80/* too many connections */
    256SNO_HACK40x100/* Uworld actions on channels */
    512SNO_GLINE0x200/* glines */
    1024SNO_NETWORK0x400/* net join/break, etc */
    2048SNO_IPMISMATCH0x800/* IP mismatches */
    4096SNO_THROTTLE0x1000/* host throttle add/remove notices */
    8192SNO_OLDREALOP0x2000/* old oper-only messages */
    16384SNO_CONNEXIT0x4000/* client connect/exit (ugh) */
    32768SNO_AUTO0x8000/* AUTO G-Lines */
    65536SNO_DEBUG0x10000/* debugging messages (DEBUGMODE only) */
    131072SNO_AUTH0x20000/* iauth status messages */
    -
    - -

    - - - - - - - - - - - - - - -
    standard +sSNO_DEFAULT (SNO_NETWORK | SNO_OPERKILL | SNO_GLINE)
    standard +s when +o/OSNO_DEFAULT | SNO_HACK2 | SNO_HACK4 | SNO_THROTTLE | SNO_OLDSNO)
    only opers may setSNO_OPER (SNO_CONNEXIT | SNO_OLDREALOP | SNO_AUTH)
    - -


    -

    Examples of Usage

    -To receive only operkills, use /mode +s 4
    -To receive operkills and glines, add the values: -
    -
    -/mode <nick> +s 516

    - -(512+4=516) -

    -

    -If you are already receiving some notices and you wish to add notices of -netjoins/breaks use: - -

    -/mode Ghostwolf +s +1024

    -

    - -

    -If you wish to stop receiving netjoin/break notices, but continue to receive -other notices, use: - -

    -/mode Ghostwolf +s -1024
    - OR
    -/mode Ghostwolf -s +1024
    -
    - -

    -A user typing /mode Ghostwolf +s will receive netsplits/joins, operkills, and g-lines.

    - -Opers who are +s will additionally receive HACK notices and anything that -was originally in sendto_ops() and wasn't changed. Only opers can choose to -receive connect/exit notices and anything that originally was in -sendtoreal_ops() and hasn't been changed (connect/exit notices also require -a #define in config.h). -

    -

    -
    -If you have further questions about server notices (implementation, etc.),
    -please consult the ircu source code and/or e-mail coder-com@undernet.org. -
    -

    - -

    - - -Return to main Documents Project page
    -
    - - - - - - diff --git a/doc/snomask.md b/doc/snomask.md new file mode 100644 index 00000000..8067aedf --- /dev/null +++ b/doc/snomask.md @@ -0,0 +1,103 @@ +# SNOMASK - Server Notice Masks + +Written by Ghostwolf, 18th June 1997. +Modified with permission by loki, 12th November 1997. + +This document gives a brief explanation of the use of server notice masks. +The mask allows clients to specify which types of server notices they will +receive when usermode `+s`. The mask may optionally be omitted, and +reasonable defaults will be used by the server. + +Usage: + +``` +/mode +s [+/-][mask] +``` + +The mask is a decimal number given as a separate parameter. A bare +number *replaces* the current mask; a number prefixed with `+` adds +those bits, `-` removes them. Using `-s` inverts the sense of the +prefix (so `/mode -s +1024` also removes bit 1024). If the +resulting mask is zero, the user drops umode `+s`; `-s` without a mask +clears everything. + +## Masks + +The authoritative list is in `include/client.h`. + +| Mask | Name | Hex value | Description | +|------:|------|-----------|-------------| +| 1 | `SNO_OLDSNO` | 0x1 | unsorted old messages | +| 2 | `SNO_SERVKILL` | 0x2 | server kills (nick collisions) | +| 4 | `SNO_OPERKILL` | 0x4 | oper kills | +| 8 | `SNO_HACK2` | 0x8 | desyncs | +| 16 | `SNO_HACK3` | 0x10 | temporary desyncs | +| 32 | `SNO_UNAUTH` | 0x20 | unauthorized connections | +| 64 | `SNO_TCPCOMMON` | 0x40 | common TCP or socket errors | +| 128 | `SNO_TOOMANY` | 0x80 | too many connections | +| 256 | `SNO_HACK4` | 0x100 | Uworld actions on channels | +| 512 | `SNO_GLINE` | 0x200 | G-lines | +| 1024 | `SNO_NETWORK` | 0x400 | net join/break, etc | +| 2048 | `SNO_IPMISMATCH` | 0x800 | IP mismatches | +| 4096 | `SNO_THROTTLE` | 0x1000 | host throttle add/remove notices | +| 8192 | `SNO_OLDREALOP` | 0x2000 | old oper-only messages | +| 16384 | `SNO_CONNEXIT` | 0x4000 | client connect/exit | +| 32768 | `SNO_AUTO` | 0x8000 | automatic G-lines | +| 65536 | `SNO_DEBUG` | 0x10000 | debugging messages (DEBUGMODE only) | +| 131072 | `SNO_AUTH` | 0x20000 | IAuth notices | + +## Defaults + +| Situation | Mask | +|-----------|------| +| standard `+s` | `SNO_DEFAULT` = `SNO_NETWORK \| SNO_OPERKILL \| SNO_GLINE` | +| standard `+s` when `+o`/`+O` | `SNO_OPERDEFAULT` = `SNO_DEFAULT \| SNO_HACK2 \| SNO_HACK4 \| SNO_THROTTLE \| SNO_OLDSNO` | +| only opers may set | `SNO_OPER` = `SNO_CONNEXIT \| SNO_OLDREALOP \| SNO_AUTH` | +| maximum for non-opers | `SNO_USER` = everything except `SNO_OPER` | + +An explicit mask from a non-opered client is silently ANDed with +`SNO_USER`, so a non-oper may request any notice type *except* +connect/exit, old oper-only messages and IAuth notices. An oper's mask +is capped at `SNO_ALL`. When a user is de-opered (`-o`/`-O`), the +`SNO_OPER` bits are removed from their mask automatically. `SNO_DEBUG` +only exists in servers compiled with DEBUGMODE. + +## Examples of usage + +To receive only oper kills: + +``` +/mode +s 4 +``` + +To receive oper kills and G-lines, add the values (512 + 4 = 516): + +``` +/mode +s 516 +``` + +If you are already receiving some notices and you wish to add notices of +net joins/breaks: + +``` +/mode +s +1024 +``` + +If you wish to stop receiving net join/break notices, but continue to +receive other notices, either of: + +``` +/mode +s -1024 +/mode -s +1024 +``` + +A non-opered user typing `/mode +s` without a mask gets +`SNO_DEFAULT`: net splits/joins, oper kills and G-lines. An oper doing +the same gets `SNO_OPERDEFAULT`, which adds desync (HACK) notices, +Uworld channel actions, host-throttle notices and the unsorted old +messages. + +Only opers can choose to receive the `SNO_OPER` types. Note that +connect/exit notices (`SNO_CONNEXIT`) are only generated at all when +the `CONNEXIT_NOTICES` feature is enabled (default `FALSE`, see +`doc/readme.features.md`). diff --git a/include/ircd_features.h b/include/ircd_features.h index 9984d0ad..4dace8b3 100644 --- a/include/ircd_features.h +++ b/include/ircd_features.h @@ -29,7 +29,7 @@ struct StatDesc; extern struct Client his; /** Contains all feature settings for ircu. - * For documentation of each, see doc/readme.features. + * For documentation of each, see doc/readme.features.md. */ enum Feature { /* Misc. features */ diff --git a/include/whocmds.h b/include/whocmds.h index 357a1752..69bcb353 100644 --- a/include/whocmds.h +++ b/include/whocmds.h @@ -16,7 +16,7 @@ struct Channel; * - Several bug fixes * - Strong performance improvement * - Added possibility to have specific fields in the output - * See readme.who for further details. + * See readme.who.md for further details. */ /* Macros used only in here by m_who and its support functions */ diff --git a/ircd/m_gline.c b/ircd/m_gline.c index fce75b05..e9eb3bff 100644 --- a/ircd/m_gline.c +++ b/ircd/m_gline.c @@ -122,7 +122,7 @@ * parv[1] = Target: server numeric * parv[2] = (+|-) * - * For other parameters, see doc/readme.gline. + * For other parameters, see doc/readme.gline.md. */ int ms_gline(struct Client *cptr, struct Client *sptr, int parc, char *parv[]) @@ -373,7 +373,7 @@ ms_gline(struct Client *cptr, struct Client *sptr, int parc, char *parv[]) * parv[0] = Sender prefix * parv[1] = [[+|-]] * - * For other parameters, see doc/readme.gline. + * For other parameters, see doc/readme.gline.md. */ int mo_gline(struct Client *cptr, struct Client *sptr, int parc, char *parv[]) diff --git a/ircd/memdebug.c b/ircd/memdebug.c index af7e5301..9dee12db 100644 --- a/ircd/memdebug.c +++ b/ircd/memdebug.c @@ -15,7 +15,7 @@ /* To use this you need to get gc6.0 from: * http://www.hpl.hp.com/personal/Hans_Boehm/gc/ * and you need to apply the patch in - * doc/debug_memleak_gc.patch to your gc6.0 tree, and reconfigure your ircd using + * doc/history/debug_memleak_gc.patch to your gc6.0 tree, and reconfigure your ircd using --with-leak-detect=path-to-gc6.0/.lib/ * You should only do this for debugging builds as it can slow things down * a bit. diff --git a/patches/.cvsignore b/patches/.cvsignore deleted file mode 100644 index 1bc5bc3d..00000000 --- a/patches/.cvsignore +++ /dev/null @@ -1 +0,0 @@ -marks diff --git a/tests/docker/ircd-hub.conf b/tests/docker/ircd-hub.conf index 9fdfd5a5..b440de7c 100644 --- a/tests/docker/ircd-hub.conf +++ b/tests/docker/ircd-hub.conf @@ -134,6 +134,6 @@ Features { # check_pings() wakes at min(PINGFREQUENCY, …); keep this low so WS keepalive # tests are not blocked for 120s when the hub has no other local clients. "PINGFREQUENCY" = "3"; -# RFC6455 server Ping interval for WebSocket ports (see readme.features) +# RFC6455 server Ping interval for WebSocket ports (see readme.features.md) "WEBSOCKET_KEEPALIVE" = "2"; };