Slightly improve bytestreams management
[iris.git] / src / xmpp / xmpp-im / s5b.h
blobc9fd9bd623958963dc3c44ff9c804daa196211ae
1 /*
2 * s5b.h - direct connection protocol via tcp
3 * Copyright (C) 2003 Justin Karneges
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 #ifndef XMPP_S5B_H
22 #define XMPP_S5B_H
24 #include <QObject>
25 #include <QList>
26 #include <QHostAddress>
28 #include "bytestream.h"
29 #include "xmpp_bytestream.h"
30 #include "xmpp/jid/jid.h"
31 #include "xmpp_task.h"
32 #include "xmpp_stanza.h"
34 class SocksClient;
35 class SocksUDP;
37 namespace XMPP
39 class StreamHost;
40 class Client;
41 class S5BConnection;
42 class S5BManager;
43 class S5BServer;
44 struct S5BRequest;
45 typedef QList<StreamHost> StreamHostList;
46 typedef QList<S5BConnection*> S5BConnectionList;
48 class S5BDatagram
50 public:
51 S5BDatagram();
52 S5BDatagram(int source, int dest, const QByteArray &data);
54 int sourcePort() const;
55 int destPort() const;
56 QByteArray data() const;
58 private:
59 int _source, _dest;
60 QByteArray _buf;
63 class S5BConnection : public BSConnection
65 Q_OBJECT
66 public:
67 enum Mode { Stream, Datagram };
69 ~S5BConnection();
71 Jid proxy() const;
72 void setProxy(const Jid &proxy);
74 void connectToJid(const Jid &peer, const QString &sid, Mode m = Stream);
75 void connectToJid(const Jid &peer, const QString &sid) {
76 connectToJid(peer, sid, Stream);
79 void accept();
80 void close();
82 Jid peer() const;
83 QString sid() const;
84 BytestreamManager* manager() const;
85 bool isRemote() const;
86 Mode mode() const;
87 int state() const;
89 bool isOpen() const;
90 void write(const QByteArray &);
91 QByteArray read(int bytes=0);
92 int bytesAvailable() const;
93 int bytesToWrite() const;
95 void writeDatagram(const S5BDatagram &);
96 S5BDatagram readDatagram();
97 int datagramsAvailable() const;
99 signals:
100 void proxyQuery(); // querying proxy for streamhost information
101 void proxyResult(bool b); // query success / fail
102 void requesting(); // sent actual S5B request (initiator only)
103 void accepted(); // target accepted (initiator only
104 void tryingHosts(const StreamHostList &hosts); // currently connecting to these hosts
105 void proxyConnect(); // connecting to proxy
106 void waitingForActivation(); // waiting for activation (target only)
107 void connected(); // connection active
108 void datagramReady();
110 private slots:
111 void doPending();
113 void sc_connectionClosed();
114 void sc_delayedCloseFinished();
115 void sc_readyRead();
116 void sc_bytesWritten(int);
117 void sc_error(int);
119 void su_packetReady(const QByteArray &buf);
121 private:
122 class Private;
123 Private *d;
125 void reset(bool clear=false);
126 void handleUDP(const QByteArray &buf);
127 void sendUDP(const QByteArray &buf);
129 friend class S5BManager;
130 void man_waitForAccept(const S5BRequest &r);
131 void man_clientReady(SocksClient *, SocksUDP *);
132 void man_udpReady(const QByteArray &buf);
133 void man_failed(int);
134 S5BConnection(S5BManager *, QObject *parent=0);
137 class S5BManager : public BytestreamManager
139 Q_OBJECT
140 public:
141 S5BManager(Client *);
142 ~S5BManager();
144 static const char* ns();
145 Client *client() const;
146 S5BServer *server() const;
147 void setServer(S5BServer *s);
149 Jid localPeer(const Jid &peer) const;
150 bool isAcceptableSID(const Jid &peer, const QString &sid) const;
152 BSConnection *createConnection();
153 S5BConnection *takeIncoming();
155 class Item;
156 class Entry;
158 protected:
159 const char* sidPrefix() const;
161 private slots:
162 void ps_incoming(const S5BRequest &req);
163 void ps_incomingUDPSuccess(const Jid &from, const QString &dstaddr);
164 void ps_incomingActivate(const Jid &from, const QString &sid, const Jid &streamHost);
165 void item_accepted();
166 void item_tryingHosts(const StreamHostList &list);
167 void item_proxyConnect();
168 void item_waitingForActivation();
169 void item_connected();
170 void item_error(int);
171 void query_finished();
173 private:
174 class Private;
175 Private *d;
177 S5BConnection *findIncoming(const Jid &from, const QString &sid) const;
178 Entry *findEntry(S5BConnection *) const;
179 Entry *findEntry(Item *) const;
180 Entry *findEntryByHash(const QString &key) const;
181 Entry *findEntryBySID(const Jid &peer, const QString &sid) const;
182 Entry *findServerEntryByHash(const QString &key) const;
184 void entryContinue(Entry *e);
185 void queryProxy(Entry *e);
186 bool targetShouldOfferProxy(Entry *e);
188 friend class S5BConnection;
189 void con_connect(S5BConnection *);
190 void con_accept(S5BConnection *);
191 void con_reject(S5BConnection *);
192 void con_unlink(S5BConnection *);
193 void con_sendUDP(S5BConnection *, const QByteArray &buf);
195 friend class S5BServer;
196 bool srv_ownsHash(const QString &key) const;
197 void srv_incomingReady(SocksClient *sc, const QString &key);
198 void srv_incomingUDP(bool init, const QHostAddress &addr, int port, const QString &key, const QByteArray &data);
199 void srv_unlink();
201 friend class Item;
202 void doSuccess(const Jid &peer, const QString &id, const Jid &streamHost);
203 void doError(const Jid &peer, const QString &id, Stanza::Error::ErrorCond, const QString &);
204 void doActivate(const Jid &peer, const QString &sid, const Jid &streamHost);
207 class S5BConnector : public QObject
209 Q_OBJECT
210 public:
211 S5BConnector(QObject *parent=0);
212 ~S5BConnector();
214 void reset();
215 void start(const Jid &self, const StreamHostList &hosts, const QString &key, bool udp, int timeout);
216 SocksClient *takeClient();
217 SocksUDP *takeUDP();
218 StreamHost streamHostUsed() const;
220 class Item;
222 signals:
223 void result(bool);
225 private slots:
226 void item_result(bool);
227 void t_timeout();
229 private:
230 class Private;
231 Private *d;
233 friend class S5BManager;
234 void man_udpSuccess(const Jid &streamHost);
237 // listens on a port for serving
238 class S5BServer : public QObject
240 Q_OBJECT
241 public:
242 S5BServer(QObject *par=0);
243 ~S5BServer();
245 bool isActive() const;
246 bool start(int port);
247 void stop();
248 int port() const;
249 void setHostList(const QStringList &);
250 QStringList hostList() const;
252 class Item;
254 private slots:
255 void ss_incomingReady();
256 void ss_incomingUDP(const QString &host, int port, const QHostAddress &addr, int sourcePort, const QByteArray &data);
257 void item_result(bool);
259 private:
260 class Private;
261 Private *d;
263 friend class S5BManager;
264 void link(S5BManager *);
265 void unlink(S5BManager *);
266 void unlinkAll();
267 const QList<S5BManager*> & managerList() const;
268 void writeUDP(const QHostAddress &addr, int port, const QByteArray &data);
271 class JT_S5B : public Task
273 Q_OBJECT
274 public:
275 JT_S5B(Task *);
276 ~JT_S5B();
278 void request(const Jid &to, const QString &sid, const StreamHostList &hosts, bool fast, bool udp=false);
279 void requestProxyInfo(const Jid &to);
280 void requestActivation(const Jid &to, const QString &sid, const Jid &target);
282 void onGo();
283 void onDisconnect();
284 bool take(const QDomElement &);
286 Jid streamHostUsed() const;
287 StreamHost proxyInfo() const;
289 private slots:
290 void t_timeout();
292 private:
293 class Private;
294 Private *d;
297 struct S5BRequest
299 Jid from;
300 QString id, sid;
301 StreamHostList hosts;
302 bool fast;
303 bool udp;
305 class JT_PushS5B : public Task
307 Q_OBJECT
308 public:
309 JT_PushS5B(Task *);
310 ~JT_PushS5B();
312 int priority() const;
314 void respondSuccess(const Jid &to, const QString &id, const Jid &streamHost);
315 void respondError(const Jid &to, const QString &id,
316 Stanza::Error::ErrorCond cond, const QString &str);
317 void sendUDPSuccess(const Jid &to, const QString &dstaddr);
318 void sendActivate(const Jid &to, const QString &sid, const Jid &streamHost);
320 bool take(const QDomElement &);
322 signals:
323 void incoming(const S5BRequest &req);
324 void incomingUDPSuccess(const Jid &from, const QString &dstaddr);
325 void incomingActivate(const Jid &from, const QString &sid, const Jid &streamHost);
328 class StreamHost
330 public:
331 StreamHost();
333 const Jid & jid() const;
334 const QString & host() const;
335 int port() const;
336 bool isProxy() const;
337 void setJid(const Jid &);
338 void setHost(const QString &);
339 void setPort(int);
340 void setIsProxy(bool);
342 private:
343 Jid j;
344 QString v_host;
345 int v_port;
346 bool proxy;
350 #endif