File indexing completed on 2024-06-23 04:03:39
0001 /* 0002 * s5b.h - direct connection protocol via tcp 0003 * Copyright (C) 2003 Justin Karneges 0004 * 0005 * This library is free software; you can redistribute it and/or 0006 * modify it under the terms of the GNU Lesser General Public 0007 * License as published by the Free Software Foundation; either 0008 * either version 2 0009 of the License, or (at your option) any later version.1 of the License, or (at your option) any later version. 0010 * 0011 * This library is distributed in the hope that it will be useful, 0012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 0013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 0014 * Lesser General Public License for more details. 0015 * 0016 * You should have received a copy of the GNU Lesser General Public 0017 * License along with this library; if not, write to the Free Software 0018 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 0019 * 0020 */ 0021 0022 #ifndef XMPP_S5B_H 0023 #define XMPP_S5B_H 0024 0025 #include <QObject> 0026 #include <QList> 0027 #include <QHostAddress> 0028 0029 #include "iris_export.h" 0030 #include "bytestream.h" 0031 #include "xmpp/jid/jid.h" 0032 #include "xmpp_task.h" 0033 0034 class SocksClient; 0035 class SocksUDP; 0036 0037 namespace XMPP 0038 { 0039 class StreamHost; 0040 class Client; 0041 class S5BConnection; 0042 class S5BManager; 0043 class S5BServer; 0044 struct S5BRequest; 0045 typedef QList<StreamHost> StreamHostList; 0046 typedef QList<S5BConnection*> S5BConnectionList; 0047 0048 class IRIS_EXPORT S5BDatagram 0049 { 0050 public: 0051 S5BDatagram(); 0052 S5BDatagram(int source, int dest, const QByteArray &data); 0053 0054 int sourcePort() const; 0055 int destPort() const; 0056 QByteArray data() const; 0057 0058 private: 0059 int _source, _dest; 0060 QByteArray _buf; 0061 }; 0062 0063 class IRIS_EXPORT S5BConnection : public ByteStream 0064 { 0065 Q_OBJECT 0066 public: 0067 enum Mode { Stream, Datagram }; 0068 enum Error { ErrRefused, ErrConnect, ErrProxy, ErrSocket }; 0069 enum State { Idle, Requesting, Connecting, WaitingForAccept, Active }; 0070 ~S5BConnection() override; 0071 0072 Jid proxy() const; 0073 void setProxy(const Jid &proxy); 0074 0075 void connectToJid(const Jid &peer, const QString &sid, Mode m = Stream); 0076 void accept(); 0077 void close() override; 0078 0079 Jid peer() const; 0080 QString sid() const; 0081 bool isRemote() const; 0082 Mode mode() const; 0083 int state() const; 0084 0085 bool isOpen() const override; 0086 void write(const QByteArray &) override; 0087 QByteArray read(int bytes=0) override; 0088 int bytesAvailable() const override; 0089 int bytesToWrite() const override; 0090 0091 void writeDatagram(const S5BDatagram &); 0092 S5BDatagram readDatagram(); 0093 int datagramsAvailable() const; 0094 0095 signals: 0096 void proxyQuery(); // querying proxy for streamhost information 0097 void proxyResult(bool b); // query success / fail 0098 void requesting(); // sent actual S5B request (initiator only) 0099 void accepted(); // target accepted (initiator only 0100 void tryingHosts(const StreamHostList &hosts); // currently connecting to these hosts 0101 void proxyConnect(); // connecting to proxy 0102 void waitingForActivation(); // waiting for activation (target only) 0103 void connected(); // connection active 0104 void datagramReady(); 0105 0106 private slots: 0107 void doPending(); 0108 0109 void sc_connectionClosed(); 0110 void sc_delayedCloseFinished(); 0111 void sc_readyRead(); 0112 void sc_bytesWritten(int); 0113 void sc_error(int); 0114 0115 void su_packetReady(const QByteArray &buf); 0116 0117 private: 0118 class Private; 0119 Private *d; 0120 0121 void reset(bool clear=false); 0122 void handleUDP(const QByteArray &buf); 0123 void sendUDP(const QByteArray &buf); 0124 0125 friend class S5BManager; 0126 void man_waitForAccept(const S5BRequest &r); 0127 void man_clientReady(SocksClient *, SocksUDP *); 0128 void man_udpReady(const QByteArray &buf); 0129 void man_failed(int); 0130 S5BConnection(S5BManager *, QObject *parent=0); 0131 }; 0132 0133 class IRIS_EXPORT S5BManager : public QObject 0134 { 0135 Q_OBJECT 0136 public: 0137 S5BManager(Client *); 0138 ~S5BManager() override; 0139 0140 Client *client() const; 0141 S5BServer *server() const; 0142 void setServer(S5BServer *s); 0143 0144 bool isAcceptableSID(const Jid &peer, const QString &sid) const; 0145 QString genUniqueSID(const Jid &peer) const; 0146 0147 S5BConnection *createConnection(); 0148 S5BConnection *takeIncoming(); 0149 0150 class Item; 0151 class Entry; 0152 0153 signals: 0154 void incomingReady(); 0155 0156 private slots: 0157 void ps_incoming(const S5BRequest &req); 0158 void ps_incomingUDPSuccess(const Jid &from, const QString &dstaddr); 0159 void ps_incomingActivate(const Jid &from, const QString &sid, const Jid &streamHost); 0160 void item_accepted(); 0161 void item_tryingHosts(const StreamHostList &list); 0162 void item_proxyConnect(); 0163 void item_waitingForActivation(); 0164 void item_connected(); 0165 void item_error(int); 0166 void query_finished(); 0167 0168 private: 0169 class Private; 0170 Private *d; 0171 0172 S5BConnection *findIncoming(const Jid &from, const QString &sid) const; 0173 Entry *findEntry(S5BConnection *) const; 0174 Entry *findEntry(Item *) const; 0175 Entry *findEntryByHash(const QString &key) const; 0176 Entry *findEntryBySID(const Jid &peer, const QString &sid) const; 0177 Entry *findServerEntryByHash(const QString &key) const; 0178 0179 void entryContinue(Entry *e); 0180 void queryProxy(Entry *e); 0181 bool targetShouldOfferProxy(Entry *e); 0182 0183 friend class S5BConnection; 0184 void con_connect(S5BConnection *); 0185 void con_accept(S5BConnection *); 0186 void con_reject(S5BConnection *); 0187 void con_unlink(S5BConnection *); 0188 void con_sendUDP(S5BConnection *, const QByteArray &buf); 0189 0190 friend class S5BServer; 0191 bool srv_ownsHash(const QString &key) const; 0192 void srv_incomingReady(SocksClient *sc, const QString &key); 0193 void srv_incomingUDP(bool init, const QHostAddress &addr, int port, const QString &key, const QByteArray &data); 0194 void srv_unlink(); 0195 0196 friend class Item; 0197 void doSuccess(const Jid &peer, const QString &id, const Jid &streamHost); 0198 void doError(const Jid &peer, const QString &id, int, const QString &); 0199 void doActivate(const Jid &peer, const QString &sid, const Jid &streamHost); 0200 }; 0201 0202 class IRIS_EXPORT S5BConnector : public QObject 0203 { 0204 Q_OBJECT 0205 public: 0206 S5BConnector(QObject *parent=0); 0207 ~S5BConnector() override; 0208 0209 void reset(); 0210 void start(const Jid &self, const StreamHostList &hosts, const QString &key, bool udp, int timeout); 0211 SocksClient *takeClient(); 0212 SocksUDP *takeUDP(); 0213 StreamHost streamHostUsed() const; 0214 0215 class Item; 0216 0217 signals: 0218 void result(bool); 0219 0220 private slots: 0221 void item_result(bool); 0222 void t_timeout(); 0223 0224 private: 0225 class Private; 0226 Private *d; 0227 0228 friend class S5BManager; 0229 void man_udpSuccess(const Jid &streamHost); 0230 }; 0231 0232 // listens on a port for serving 0233 class IRIS_EXPORT S5BServer : public QObject 0234 { 0235 Q_OBJECT 0236 public: 0237 S5BServer(QObject *par=0); 0238 ~S5BServer() override; 0239 0240 bool isActive() const; 0241 bool start(int port); 0242 void stop(); 0243 int port() const; 0244 void setHostList(const QStringList &); 0245 QStringList hostList() const; 0246 0247 class Item; 0248 0249 private slots: 0250 void ss_incomingReady(); 0251 void ss_incomingUDP(const QString &host, int port, const QHostAddress &addr, int sourcePort, const QByteArray &data); 0252 void item_result(bool); 0253 0254 private: 0255 class Private; 0256 Private *d; 0257 0258 friend class S5BManager; 0259 void link(S5BManager *); 0260 void unlink(S5BManager *); 0261 void unlinkAll(); 0262 const QList<S5BManager*> & managerList() const; 0263 void writeUDP(const QHostAddress &addr, int port, const QByteArray &data); 0264 }; 0265 0266 class IRIS_EXPORT JT_S5B : public Task 0267 { 0268 Q_OBJECT 0269 public: 0270 JT_S5B(Task *); 0271 ~JT_S5B() override; 0272 0273 void request(const Jid &to, const QString &sid, const StreamHostList &hosts, bool fast, bool udp=false); 0274 void requestProxyInfo(const Jid &to); 0275 void requestActivation(const Jid &to, const QString &sid, const Jid &target); 0276 0277 void onGo() override; 0278 void onDisconnect() override; 0279 bool take(const QDomElement &) override; 0280 0281 Jid streamHostUsed() const; 0282 StreamHost proxyInfo() const; 0283 0284 private slots: 0285 void t_timeout(); 0286 0287 private: 0288 class Private; 0289 Private *d; 0290 }; 0291 0292 struct IRIS_EXPORT S5BRequest 0293 { 0294 Jid from; 0295 QString id, sid; 0296 StreamHostList hosts; 0297 bool fast; 0298 bool udp; 0299 }; 0300 class IRIS_EXPORT JT_PushS5B : public Task 0301 { 0302 Q_OBJECT 0303 public: 0304 JT_PushS5B(Task *); 0305 ~JT_PushS5B() override; 0306 0307 int priority() const; 0308 0309 void respondSuccess(const Jid &to, const QString &id, const Jid &streamHost); 0310 void respondError(const Jid &to, const QString &id, int code, const QString &str); 0311 void sendUDPSuccess(const Jid &to, const QString &dstaddr); 0312 void sendActivate(const Jid &to, const QString &sid, const Jid &streamHost); 0313 0314 bool take(const QDomElement &) override; 0315 0316 signals: 0317 void incoming(const S5BRequest &req); 0318 void incomingUDPSuccess(const Jid &from, const QString &dstaddr); 0319 void incomingActivate(const Jid &from, const QString &sid, const Jid &streamHost); 0320 }; 0321 0322 class IRIS_EXPORT StreamHost 0323 { 0324 public: 0325 StreamHost(); 0326 0327 const Jid & jid() const; 0328 const QString & host() const; 0329 int port() const; 0330 bool isProxy() const; 0331 void setJid(const Jid &); 0332 void setHost(const QString &); 0333 void setPort(int); 0334 void setIsProxy(bool); 0335 0336 private: 0337 Jid j; 0338 QString v_host; 0339 int v_port; 0340 bool proxy; 0341 }; 0342 } 0343 0344 #endif