Coverage Report

Created: 2025-08-28 06:45

/src/znc/include/znc/IRCSock.h
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * Copyright (C) 2004-2025 ZNC, see the NOTICE file for details.
3
 *
4
 * Licensed under the Apache License, Version 2.0 (the "License");
5
 * you may not use this file except in compliance with the License.
6
 * You may obtain a copy of the License at
7
 *
8
 *     http://www.apache.org/licenses/LICENSE-2.0
9
 *
10
 * Unless required by applicable law or agreed to in writing, software
11
 * distributed under the License is distributed on an "AS IS" BASIS,
12
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
 * See the License for the specific language governing permissions and
14
 * limitations under the License.
15
 */
16
17
#ifndef ZNC_IRCSOCK_H
18
#define ZNC_IRCSOCK_H
19
20
#include <znc/zncconfig.h>
21
#include <znc/Socket.h>
22
#include <znc/Nick.h>
23
#include <znc/Message.h>
24
25
#include <deque>
26
27
// Forward Declarations
28
class CChan;
29
class CUser;
30
class CIRCNetwork;
31
class CClient;
32
// !Forward Declarations
33
34
// TODO: This class needs new name
35
class CIRCSock : public CIRCSocket {
36
  public:
37
    CIRCSock(CIRCNetwork* pNetwork);
38
    virtual ~CIRCSock();
39
40
    CIRCSock(const CIRCSock&) = delete;
41
    CIRCSock& operator=(const CIRCSock&) = delete;
42
43
    typedef enum {
44
        // These values must line up with their position in the CHANMODE
45
        // argument to raw 005
46
        ListArg = 0,
47
        HasArg = 1,
48
        ArgWhenSet = 2,
49
        NoArg = 3
50
    } EChanModeArgs;
51
52
    void ReadLine(const CString& sData) override;
53
    void Connected() override;
54
    void Disconnected() override;
55
    void ConnectionRefused() override;
56
    void SockError(int iErrno, const CString& sDescription) override;
57
    void Timeout() override;
58
    void ReachedMaxBuffer() override;
59
#ifdef HAVE_LIBSSL
60
    void SSLCertError(X509* pCert) override;
61
#endif
62
    /** Sends a raw data line to the server.
63
     *  @param sLine The line to be sent.
64
     *
65
     *  The line is first passed \e unmodified to the \ref
66
     *  CModule::OnSendToIRC() module hook. If no module halts the process,
67
     *  the line is then sent to the server.
68
     *
69
     *  Prefer \l PutIRC() instead.
70
     */
71
    void PutIRCRaw(const CString& sLine);
72
    /** Sends a message to the server.
73
     *  See \l PutIRC(const CMessage&) for details.
74
     */
75
    void PutIRC(const CString& sLine);
76
    /** Sends a message to the server.
77
     *  @param  Message The message to be sent.
78
     *  @note   Only known and compatible messages and tags are sent.
79
     *
80
     *  This method can delay the delivery of the message to honor protection
81
     *  from flood.
82
     *
83
     *  This method ensures that only tags, that were negotiated with CAP REQ
84
     *  and CAP ACK, are sent. Not all IRC server are capable of handling all
85
     *  messages and tags. Thus, in order to stay compatible with a variety of
86
     *  IRC servers, ZNC has to filter out messages and tags that the server
87
     *  has not explicitly acknowleged.
88
     *
89
     *  Additional tags can be added via \l CIRCSock::SetTagSupport().
90
     *
91
     *  @warning Bypassing the filter may cause troubles to some older IRC
92
     *  servers.
93
     *
94
     *  It is possible to bypass the filter by converting a message to a string
95
     *  using \l CMessage::ToString(), and passing the resulting raw line to the
96
     *  \l CIRCSock::PutIRCRaw(const CString& sLine):
97
     *  \code
98
     *  pServer->PutIRCRaw(Message.ToString());
99
     *  \endcode
100
     */
101
    void PutIRC(const CMessage& Message);
102
    void PutIRCQuick(const CString& sLine);  //!< Should be used for PONG only
103
    void ResetChans();
104
    void Quit(const CString& sQuitMsg = "");
105
106
    /** You can call this from CModule::OnServerCapResult to suspend
107
     *  sending other CAP requests and CAP END for a while. Each
108
     *  call to PauseCap should be balanced with a call to ResumeCap.
109
     */
110
    void PauseCap();
111
    /** If you used PauseCap, call this when CAP negotiation and logging in
112
     *  should be resumed again.
113
     */
114
    void ResumeCap();
115
    
116
0
    bool IsTagEnabled(const CString& sTag) const {
117
0
        return 1 == m_ssSupportedTags.count(sTag);
118
0
    }
119
    /** Registers a tag as being supported or unsupported by the server.
120
     *  This doesn't affect tags which the server sends.
121
     *  @param sTag The tag to register.
122
     *  @param bState Whether the client supports the tag.
123
     */
124
    void SetTagSupport(const CString& sTag, bool bState);
125
126
    // Setters
127
0
    void SetPass(const CString& s) { m_sPass = s; }
128
    // !Setters
129
130
    // Getters
131
0
    unsigned int GetMaxNickLen() const { return m_uMaxNickLen; }
132
    EChanModeArgs GetModeType(char cMode) const;
133
    char GetPermFromMode(char cMode) const;
134
    char GetModeFromPerm(char cPerm) const;
135
0
    const std::map<char, EChanModeArgs>& GetChanModes() const {
136
0
        return m_mceChanModes;
137
0
    }
138
0
    bool IsPermChar(const char c) const {
139
0
        return (c != '\0' && GetPerms().find(c) != CString::npos);
140
0
    }
141
0
    bool IsPermMode(const char c) const {
142
0
        return (c != '\0' && GetPermModes().find(c) != CString::npos);
143
0
    }
144
0
    const CString& GetPerms() const { return m_sPerms; }
145
0
    const CString& GetPermModes() const { return m_sPermModes; }
146
0
    CString GetNickMask() const { return m_Nick.GetNickMask(); }
147
0
    const CString& GetNick() const { return m_Nick.GetNick(); }
148
0
    const CString& GetPass() const { return m_sPass; }
149
0
    CIRCNetwork* GetNetwork() const { return m_pNetwork; }
150
0
    bool HasNamesx() const { return m_bNamesx; }
151
0
    bool HasUHNames() const { return m_bUHNames; }
152
0
    bool HasAwayNotify() const { return m_bAwayNotify; }
153
0
    bool HasAccountNotify() const { return m_bAccountNotify; }
154
0
    bool HasExtendedJoin() const { return m_bExtendedJoin; }
155
0
    bool HasServerTime() const { return m_bServerTime; }
156
0
    bool HasMessageTagCap() const { return m_bMessageTagCap; }
157
0
    const std::set<char>& GetUserModes() const { return m_scUserModes; }
158
    // This is true if we are past raw 001
159
0
    bool IsAuthed() const { return m_bAuthed; }
160
0
    const SCString& GetAcceptedCaps() const { return m_ssAcceptedCaps; }
161
0
    bool IsCapAccepted(const CString& sCap) {
162
0
        return 1 == m_ssAcceptedCaps.count(sCap);
163
0
    }
164
    CString GetCapLsValue(const CString& sKey,
165
                          const CString& sDefault = "") const;
166
0
    const MCString& GetISupport() const { return m_mISupport; }
167
    CString GetISupport(const CString& sKey,
168
                        const CString& sDefault = "") const;
169
    // !Getters
170
171
    // TODO move this function to CIRCNetwork and make it non-static?
172
    static bool IsFloodProtected(double fRate);
173
174
    bool IsNickVisibleInAttachedChannels(const CString& sNick) const;
175
176
  private:
177
    // Message Handlers
178
    bool OnAccountMessage(CMessage& Message);
179
    bool OnActionMessage(CActionMessage& Message);
180
    bool OnAwayMessage(CMessage& Message);
181
    bool OnCapabilityMessage(CMessage& Message);
182
    bool OnChgHostMessage(CChgHostMessage& Message);
183
    bool OnCTCPMessage(CCTCPMessage& Message);
184
    bool OnErrorMessage(CMessage& Message);
185
    bool OnInviteMessage(CInviteMessage& Message);
186
    bool OnJoinMessage(CJoinMessage& Message);
187
    bool OnKickMessage(CKickMessage& Message);
188
    bool OnModeMessage(CModeMessage& Message);
189
    bool OnNickMessage(CNickMessage& Message);
190
    bool OnNoticeMessage(CNoticeMessage& Message);
191
    bool OnNumericMessage(CNumericMessage& Message);
192
    bool OnPartMessage(CPartMessage& Message);
193
    bool OnPingMessage(CMessage& Message);
194
    bool OnPongMessage(CMessage& Message);
195
    bool OnQuitMessage(CQuitMessage& Message);
196
    bool OnTagMessage(CTargetMessage& Message);
197
    bool OnTextMessage(CTextMessage& Message);
198
    bool OnTopicMessage(CTopicMessage& Message);
199
    bool OnWallopsMessage(CMessage& Message);
200
    bool OnServerCapAvailable(const CString& sCap, const CString& sValue);
201
    // !Message Handlers
202
203
    void SetNick(const CString& sNick);
204
    void ParseISupport(const CMessage& Message);
205
    // This is called when we connect and the nick we want is already taken
206
    void SendAltNick(const CString& sBadNick);
207
    void SendNextCap();
208
    void TrySend();
209
210
  protected:
211
    bool m_bAuthed;
212
    bool m_bNamesx;
213
    bool m_bUHNames;
214
    bool m_bAwayNotify;
215
    bool m_bAccountNotify;
216
    bool m_bExtendedJoin;
217
    bool m_bServerTime;
218
    bool m_bMessageTagCap;
219
    CString m_sPerms;
220
    CString m_sPermModes;
221
    std::set<char> m_scUserModes;
222
    std::map<char, EChanModeArgs> m_mceChanModes;
223
    CIRCNetwork* m_pNetwork;
224
    CNick m_Nick;
225
    CString m_sPass;
226
    std::map<CString, CChan*> m_msChans;
227
    unsigned int m_uMaxNickLen;
228
    unsigned int m_uCapPaused;
229
    SCString m_ssAcceptedCaps;
230
    SCString m_ssPendingCaps;
231
    SCString m_ssPendingCapsPhase2;
232
    MCString m_msCapLsValues;
233
    unsigned long long m_lastCTCP;
234
    unsigned int m_uNumCTCP;
235
    static const unsigned long long m_uCTCPFloodTime;
236
    static const unsigned int m_uCTCPFloodCount;
237
    MCString m_mISupport;
238
    std::deque<CMessage> m_vSendQueue;
239
    short int m_iSendsAllowed;
240
    unsigned short int m_uFloodBurst;
241
    double m_fFloodRate;
242
    bool m_bFloodProtection;
243
    unsigned long long m_lastFloodWarned;
244
    SCString m_ssSupportedTags;
245
    VCString m_vsSSLError;
246
247
    friend class CIRCFloodTimer;
248
    friend class CCoreCaps;
249
};
250
251
#endif  // !ZNC_IRCSOCK_H