QXmpp  Version: 1.7.1
QXmppOutgoingClient.h
1 // SPDX-FileCopyrightText: 2010 Manjeet Dahiya <manjeetdahiya@gmail.com>
2 // SPDX-FileCopyrightText: 2010 Jeremy LainĂ© <jeremy.laine@m4x.org>
3 // SPDX-FileCopyrightText: 2020 Linus Jahn <lnj@kaidan.im>
4 //
5 // SPDX-License-Identifier: LGPL-2.1-or-later
6 
7 #ifndef QXMPPOUTGOINGCLIENT_H
8 #define QXMPPOUTGOINGCLIENT_H
9 
10 #include "QXmppAuthenticationError.h"
11 #include "QXmppBindError.h"
12 #include "QXmppClient.h"
13 #include "QXmppStanza.h"
14 #include "QXmppStreamError.h"
15 
16 #include <QAbstractSocket>
17 
18 class QDomElement;
19 class QSslError;
20 class QSslSocket;
21 
22 class QXmppConfiguration;
23 class QXmppPresence;
24 class QXmppIq;
25 class QXmppMessage;
27 class QXmppOutgoingClientPrivate;
28 class TestClient;
29 
30 namespace QXmpp::Private {
31 class C2sStreamManager;
32 class OutgoingIqManager;
33 class PingManager;
34 class StreamAckManager;
35 class XmppSocket;
36 
37 enum HandleElementResult {
38  Accepted,
39  Rejected,
40  Finished,
41 };
42 } // namespace QXmpp::Private
43 
44 namespace QXmpp::Private::Sasl2 {
45 struct StreamFeature;
46 }
47 
48 // The QXmppOutgoingClient class represents an outgoing XMPP stream to an XMPP server.
49 class QXMPP_EXPORT QXmppOutgoingClient : public QXmppLoggable
50 {
51  Q_OBJECT
52 
53 public:
54  using IqResult = std::variant<QDomElement, QXmppError>;
55  using ConnectionError = std::variant<QAbstractSocket::SocketError, QXmpp::TimeoutError, QXmpp::StreamError, QXmpp::AuthenticationError, QXmpp::BindError>;
56 
57  explicit QXmppOutgoingClient(QObject *parent);
58  ~QXmppOutgoingClient() override;
59 
60  void connectToHost();
61  void disconnectFromHost();
62  bool isAuthenticated() const;
63  bool isConnected() const;
64  bool isClientStateIndicationEnabled() const;
65  QXmppTask<IqResult> sendIq(QXmppIq &&);
66 
68  QSslSocket *socket() const;
69  QXmppStanza::Error::Condition xmppStreamError();
70 
71  QXmppConfiguration &configuration();
72 
73  QXmpp::Private::XmppSocket &xmppSocket() const;
74  QXmpp::Private::StreamAckManager &streamAckManager() const;
75  QXmpp::Private::OutgoingIqManager &iqManager() const;
76  QXmpp::Private::C2sStreamManager &c2sStreamManager();
77 
79  Q_SIGNAL void connected();
80 
82  Q_SIGNAL void disconnected();
83 
85  Q_SIGNAL void errorOccurred(const QString &text, const QXmppOutgoingClient::ConnectionError &details, QXmppClient::Error oldError);
86 
88  Q_SIGNAL void elementReceived(const QDomElement &element, bool &handled);
89 
91  Q_SIGNAL void presenceReceived(const QXmppPresence &);
92 
94  Q_SIGNAL void messageReceived(const QXmppMessage &);
95 
98  Q_SIGNAL void iqReceived(const QXmppIq &);
99 
101  Q_SIGNAL void sslErrors(const QList<QSslError> &errors);
102 
103 private:
104  void handleStart();
105  void handlePacketReceived(const QDomElement &element);
106  QXmpp::Private::HandleElementResult handleElement(const QDomElement &nodeRecv);
107  void handleStream(const QDomElement &element);
108 
109  void _q_socketDisconnected();
110  void socketError(QAbstractSocket::SocketError);
111  void socketSslErrors(const QList<QSslError> &);
112 
113  void startSasl2Auth(const QXmpp::Private::Sasl2::StreamFeature &sasl2Feature);
114  void startNonSaslAuth();
115  void startResourceBinding();
116  void onSMResumeFinished();
117  void onSMEnableFinished();
118  void throwKeepAliveError();
119 
120  // for unit tests, see TestClient
121  void enableStreamManagement(bool resetSequenceNumber);
122  bool handleIqResponse(const QDomElement &);
123 
124  friend class QXmppOutgoingClientPrivate;
125  friend class QXmpp::Private::PingManager;
126  friend class QXmpp::Private::C2sStreamManager;
127  friend class TestClient;
128 
129  const std::unique_ptr<QXmppOutgoingClientPrivate> d;
130 };
131 
132 namespace QXmpp::Private {
133 
134 class C2sStreamManager
135 {
136 public:
137  explicit C2sStreamManager(QXmppOutgoingClient *q);
138 
139  bool handleElement(const QDomElement &);
140  bool hasResumeAddress() const { return m_canResume && !m_resumeHost.isEmpty() && m_resumePort; }
141  std::pair<QString, quint16> resumeAddress() const { return { m_resumeHost, m_resumePort }; }
142  void onStreamStart();
143  void onStreamFeatures(const QXmppStreamFeatures &);
144  void onDisconnecting();
145  bool canResume() const { return m_canResume; }
146  bool enabled() const { return m_enabled; }
147  bool streamResumed() const { return m_streamResumed; }
148  bool canRequestResume() const { return m_smAvailable && m_canResume; }
149  void requestResume();
150  bool canRequestEnable() const { return m_smAvailable; }
151  void requestEnable();
152 
153 private:
154  friend class ::TestClient;
155 
156  bool setResumeAddress(const QString &address);
157  void setEnabled(bool enabled) { m_enabled = enabled; }
158  void setResumed(bool resumed) { m_streamResumed = resumed; }
159 
160  QXmppOutgoingClient *q;
161 
162  bool m_smAvailable = false;
163  QString m_smId;
164  bool m_canResume = false;
165  bool m_isResuming = false;
166  QString m_resumeHost;
167  quint16 m_resumePort = 0;
168  bool m_enabled = false;
169  bool m_streamResumed = false;
170 };
171 
172 } // namespace QXmpp::Private
173 
174 #endif // QXMPPOUTGOINGCLIENT_H
Error
Definition: QXmppClient.h:99
The QXmppConfiguration class holds configuration options.
Definition: QXmppConfiguration.h:32
The QXmppIq class is the base class for all IQs.
Definition: QXmppIq.h:23
The QXmppLoggable class represents a source of logging messages.
Definition: QXmppLogger.h:110
The QXmppMessage class represents an XMPP message.
Definition: QXmppMessage.h:39
The QXmppPresence class represents an XMPP presence stanza.
Definition: QXmppPresence.h:21
Condition
A detailed condition of the error.
Definition: QXmppStanza.h:110
The QXmppStreamFeatures class represents the features returned by an XMPP server or client.
Definition: QXmppStreamFeatures.h:23
Definition: QXmppTask.h:62