summaryrefslogtreecommitdiff
path: root/docs/IRCD
blob: 7e7c4e163ddc6674144ec248d1c902945fbf278b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
How To Add IRCd Support
-----------------------

1) Files to Edit
2) The Code
3) The IRCDVar struct
4) Modes
5) Functions / Events
6) CAPAB/PROTOCTL 
7) IRCDProto Class

1) Files to Edit

    When preparing to add supprt to Anope for your IRCd, you need to edit
    the following files

    A) Make a copy of the .cpp file of the IRCd that matches the IRCd that
       you are attempting to add support for best.
    B) Add your IRCd into the supported IRCds in example.conf

2) The Code

    Here is where the code of the .cpp file comes in. Be prepared to spend at
    least an hour, if not longer, going over the code and getting it right;
    Especially if you are setting up an ircd that is completely different
    than the one you used as a base. This section covers the majority of the
    code that is in use. 

    The first bit of code you will face is the IRCDVar structure, This is one
    of two structs which holds your IRCd information; This allows you to quickly
    setup your specific ircd.

        IRCDVar myIrcd[] = { };

    This struct contains your basic IRCd functions. Your base source file has
    the list of all available variables; note that you should not swap any
    around, or you will break stuff. Here is a brief description of the usage
    of each.

    1) Name: This member tells Anope about the IRCD's name. It may contain
             text about it's name and version. This is used to identify the
             build on startup.

    2) Pseudo Client Mode: This is the user mode set by Anope on all BotServ
                           bots. Normally you want this to be a some form of
                           service or bot flag; you can use + for no mode at
                           all.

    3) Max Channelmode Symbols: This is the total number of possible channel
                                 modes that can appear before a nick. Do
                                 remember to count each possible mode, so +ov
                                 is 2.

    4) SVSNICK: Can the ircd use SVSNICK to change some ones nick? Otherwise,
                 KILL is used. Use 1 for yes, 0 for no.

    5) VHOST: Can a user's host be changed on the fly? Enabling this allow
               HostServ online. Use 1 for yes, 0 for no.

    6) SNLINE: Does the IRCd support realname (geocs) bans? Use 1 for yes,
                0 for no.

    7) SQLINE: Does the IRCd support nick bans? Use 1 for yes, 0 for no.

    8) SZLINE: Does the IRCd support SZLINES? Use 1 for yes, 0 for no.

    10) Join to Message: Services must join a channel to send any message to
                         that channel (cannot override +n). Use 1 for yes,
                         0 for no.

    11) SQline Channels: The IRCd's supports banning channel names via
                         SQLINES. Use 1 for yes, 0 for no.

    12) Quit On Kill: When we (SVS)KILL a user, does the IRCd send back a
                      QUIT message for that user? Use 1 for yes, 0 for no.

    13) SVSMODE UNBAN: We can use SVSMODE to unban hosts from a channel. Use
                    1 for yes, 0 for no.

    14) Reverse: We can do a reverse check when unbanning. For use with 
                 DreamForge based IRCd's. Use 1 for yes, 0 for no.

    15) vIdent: Support for including a user's ident in their vHost. Use
                1 for yes, 0 for no.

    16) SVSHOLD: Support for temporarily 'holding' a nick, instead of using
                 a nick enforcer client. Use 1 for yes, 0 for no.

    17) TS on MODE: We need to send a timestamp when modes are being changed.
                    Use 1 for yes, 0 for no.

    18) Umode: We can use OperServ to change a user's mode. Use 1 for yes,
               0 for no.

    19) OMODE: We can use OperServ to give some user a temporary O:LINE.
               Use 1 for yes, 0 for no.

    20) No Knock Requires +i: Does the No Knock channel mode require invite
                              only channels? Use 1 for yes, 0 for no.
    
    21) SVSMODE UCMODE: Can we clear user channel modes with SVSMODE? Use
                        1 for yes, 0 for no.

    22) SGline Enforce: Does the IRCd enforce SNLINES for us or do we need to
                        do so? Use 1 for yes, 0 for no.

    23) TS6: Does the IRCd support TS6? Use 1 for yes, 0 for no.

    24) Channel CIDR: Set to 1 if channel bans, excepts and invites
                      support CIDR masks. Expected syntax: *!*@ip/mask.
                      When set to 1, anope will only parse strict CIDR masks.
                      IRCd's that try to correct invalid CIDR's (like nefarious)
                      will need a custom implementation in the core.
                      Contact the anope Dev Team if this is the case.
                      Set to 0 if CIDR's are not supported by your IRCd.

    25) Global TLD Prefix: Prefix used to send global messages, should probably
                           be "$"

    26) Max Modes: The max number of mode changes we can send in one line

3) Modes 

   Anope is told about modes in the protocol module.
   For the most part, the syntax for adding channel and user modes are:
   
   ModeManager::AddUserMode(new UserMode(UMODE_NETADMIN, "UMODE_NETADMIN", 'N'));
   Where 'N' is the char for the mode, and UMODE_NETADMIN shows what the
   mode does. Or:

   ModeManager::AddChannelMode(new ChannelMode(CMODE_BLOCKCOLOR, "CMODE_BLOCKCOLOR", 'c'));
   Where 'c' is the char for the mode and CMODE_BLOCKCOLOR shows what
   the mode does

   A full list of valid mode names for the second param can be found
   in services.h in the enum for ChannelModeName and UserModeName
   If necessary, you can add additional modes to this list.

   Adding simple modes with parameters is similar, instead adding a
   'new ChannelMode', use 'new ChannelModeParam', set the third optional
   arg of ChannelModeParam to false if the param should NOT be sent when unsetting
   it. Eg:

   ModeManager::AddChannelMode(new ChannelModeParam(CMODE_JOINFLOOD, "CMODE_JOINFLOOD", 'j', true));

   Anope will internally track the params, and they can be retrieved through
   Channel::GetParam();

   If you want to make param validity checking for a mode, you must create a new
   class which inherits from ChannelModeParam and overload the IsValid function.
   Modes CMODE_OPERONLY, CMODE_ADMINONLY, and CMODE_REGISTERED already exist
   internally as classes, to overload the CanSet function to disable non opers
   from mlocking (or in CMODE_REGISTERED's case, anyone) from setting them.
   This should be added like:

   ModeManager::AddChannelMode(new ChannelModeOper('O'));

   The CMODE_FLOOD param also has its own class, but due to the wide range of
   valid parameters accepted across IRCds, your protocol module MUST have the
   IsValid function for this.

   bool ChannelModeFlood::IsValid(const Anope::string &value) { }

4) Functions and Events

    A brief word about functions and events. All events are captured by creating a Message struct
    with the name of the message and the callback function:

    Message my_message("MESSAGE", do_my_messsage);

    Each message should have a message handler if its important enough to be
    processed by services. All event functions should be formed like this:

	bool do_my_message(const Anope::string &source, const std::vector<Anope::string> &params)
        {
		return true;
        }

    They will receive the source; this can be empty at times depending on the
    event. Next, params holds the arguments for the event. Events are likely to
    pass to various upper level event handlers; see the previous ircd source for
    how they handle these events.

5) CAPAB/PROTOCTL

    Most IRCD send a CAPAB or PROTOCTL line so that they can work out what
    the other end of the connection is capable of doing. Anope has a function
    to read these lines and set itself up to to handle these events better.
    When adding support for your ircd, take the following steps.
    
    1) In the module constructor you must tell Anope what the uplink is capable of that
       isn't already passed in the CAPAB/PROTOCTL, you do this by something similar to:

       CapabType c[] = { CAPAB_NOQUIT, CAPAB_NICKIP, CAPAB_ZIP, CAPAB_TOKEN, CAPAB_SSJ3, CAPAB_NICK2, CAPAB_VL, CAPAB_TLKEXT, CAPAB_CHANMODE, CAPAB_SJB64, CAPAB_NICKCHARS };
       for (unsigned i = 0; i < 11; ++i)
           Capab.SetFlag(c[i]);

       Anything else given to Anope in the CAPAB/PROTOCTL message will be handled later by CapabParse.

       The available CAPAB options are:

       --------------------------------------------------------------------------
       Define          |  Description
       ----------------|------------|-----------|--------------------------------
       CAPAB_NOQUIT    |  NOQUIT protocol support
       CAPAB_TSMODE    |  Chanmodes are timestamped
       CAPAB_UNCONNECT |  UNCONNECT protocol support
       CAPAB_NICKIP    |  IP sent in the NICK line
       CAPAB_NSJOIN    |  Smart SJOIN support
       CAPAB_ZIP       |  Support for gzipped links
       CAPAB_BURST     |  Supports BURST command
       CAPAB_TS3       |  Support for TS3 protocol
       CAPAB_TS5       |  Support for TS5 protocol
       CAPAB_DKEY      |  DH-Key exchange using DKEY
       CAPAB_DOZIP     |  Link traffic will be gzipped
       CAPAB_DODKEY    |  Do DKEY with this link
       CAPAB_QS        |  Supports quit storm removal
       CAPAB_SCS       |  String Cache System support
       CAPAB_PT4       |  Support for PT4 protocol
       CAPAB_UID       |  Support for UIDs
       CAPAB_KNOCK     |  Supports KNOCK
       CAPAB_CLIENT    |  Supports CLIENT
       CAPAB_IPV6      |  Support for IPv6 addresses
       CAPAB_SSJ5      |  Smart Join protocol 5 support
       CAPAB_SN2       |  Support for SN2 protocol
       CAPAB_VHOST     |  Supports VHOST protocol
       CAPAB_TOKEN     |  Supports s2s tokens
       CAPAB_SSJ3      |  Smart Join protocol 3 support
       CAPAB_NICK2     |  Support for extended NICK (v2)
       CAPAB_UMODE2    |  Supports UMODE2 command
       CAPAB_VL        |  VLine information in info field
       CAPAB_TLKEXT    |  Not 8, but 10 params in TKL's
       CAPAB_CHANMODE  |  Channel modes are passed here
       CAPAB_SJB64     |  SJOIN timestamps are base64 encoded
       CAPAB_NICKCHARS |  Character set used by the IRCD for nicks

    2) Ensure that the CAPAB/PROTOCTL event his handled correctly. 

        A) In the function module constructor make sure that you have the
           following two lines:

           Message message_capab("CAPAB", event_capab);	   

        B) Add the function to handle the event

            bool event_capab(const Anope::string &source, const std::vector<Anope::string> &params)
            {
                CapabParse(params);
                return true;
            }

           This function should call the CapabParse function which parses
           the received CAPAB/PROTOCTL line.

6) IRCDProto Class

    The IRCDProto class is set up like:

    class MyIRCdProto : public IRCDProto { } ircdproto;

    And told to Anope through the

    pmodule_ircd_proto(&ircd_proto);

    function.

    This is used for sending out specific messages from Anope to your IRCd.
    A list of all of the valid function names to overload and their args
    are in services.h. If the protocol module you are editing is similar enough
    to the IRCd you are adding support for, many of these probably won't need to
    be changed.