1 /* 2 * s5b.h - direct connection protocol via tcp 3 * Copyright (C) 2003 Justin Karneges 4 * 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 * either version 2 9 of the License, or (at your option) any later version.1 of the License, or (at your option) any later version. 10 * 11 * This library is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 * Lesser General Public License for more details. 15 * 16 * You should have received a copy of the GNU Lesser General Public 17 * License along with this library; if not, write to the Free Software 18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 * 20 */ 21 22 #ifndef XMPP_S5B_H 23 #define XMPP_S5B_H 24 25 #include <QObject> 26 #include <QList> 27 #include <QHostAddress> 28 29 #include "iris_export.h" 30 #include "bytestream.h" 31 #include "xmpp/jid/jid.h" 32 #include "xmpp_task.h" 33 34 class SocksClient; 35 class SocksUDP; 36 37 namespace XMPP 38 { 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; 47 48 class IRIS_EXPORT S5BDatagram 49 { 50 public: 51 S5BDatagram(); 52 S5BDatagram(int source, int dest, const QByteArray &data); 53 54 int sourcePort() const; 55 int destPort() const; 56 QByteArray data() const; 57 58 private: 59 int _source, _dest; 60 QByteArray _buf; 61 }; 62 63 class IRIS_EXPORT S5BConnection : public ByteStream 64 { 65 Q_OBJECT 66 public: 67 enum Mode { Stream, Datagram }; 68 enum Error { ErrRefused, ErrConnect, ErrProxy, ErrSocket }; 69 enum State { Idle, Requesting, Connecting, WaitingForAccept, Active }; 70 ~S5BConnection() override; 71 72 Jid proxy() const; 73 void setProxy(const Jid &proxy); 74 75 void connectToJid(const Jid &peer, const QString &sid, Mode m = Stream); 76 void accept(); 77 void close() override; 78 79 Jid peer() const; 80 QString sid() const; 81 bool isRemote() const; 82 Mode mode() const; 83 int state() const; 84 85 bool isOpen() const override; 86 void write(const QByteArray &) override; 87 QByteArray read(int bytes=0) override; 88 int bytesAvailable() const override; 89 int bytesToWrite() const override; 90 91 void writeDatagram(const S5BDatagram &); 92 S5BDatagram readDatagram(); 93 int datagramsAvailable() const; 94 95 signals: 96 void proxyQuery(); // querying proxy for streamhost information 97 void proxyResult(bool b); // query success / fail 98 void requesting(); // sent actual S5B request (initiator only) 99 void accepted(); // target accepted (initiator only 100 void tryingHosts(const StreamHostList &hosts); // currently connecting to these hosts 101 void proxyConnect(); // connecting to proxy 102 void waitingForActivation(); // waiting for activation (target only) 103 void connected(); // connection active 104 void datagramReady(); 105 106 private slots: 107 void doPending(); 108 109 void sc_connectionClosed(); 110 void sc_delayedCloseFinished(); 111 void sc_readyRead(); 112 void sc_bytesWritten(int); 113 void sc_error(int); 114 115 void su_packetReady(const QByteArray &buf); 116 117 private: 118 class Private; 119 Private *d; 120 121 void reset(bool clear=false); 122 void handleUDP(const QByteArray &buf); 123 void sendUDP(const QByteArray &buf); 124 125 friend class S5BManager; 126 void man_waitForAccept(const S5BRequest &r); 127 void man_clientReady(SocksClient *, SocksUDP *); 128 void man_udpReady(const QByteArray &buf); 129 void man_failed(int); 130 S5BConnection(S5BManager *, QObject *parent=0); 131 }; 132 133 class IRIS_EXPORT S5BManager : public QObject 134 { 135 Q_OBJECT 136 public: 137 S5BManager(Client *); 138 ~S5BManager() override; 139 140 Client *client() const; 141 S5BServer *server() const; 142 void setServer(S5BServer *s); 143 144 bool isAcceptableSID(const Jid &peer, const QString &sid) const; 145 QString genUniqueSID(const Jid &peer) const; 146 147 S5BConnection *createConnection(); 148 S5BConnection *takeIncoming(); 149 150 class Item; 151 class Entry; 152 153 signals: 154 void incomingReady(); 155 156 private slots: 157 void ps_incoming(const S5BRequest &req); 158 void ps_incomingUDPSuccess(const Jid &from, const QString &dstaddr); 159 void ps_incomingActivate(const Jid &from, const QString &sid, const Jid &streamHost); 160 void item_accepted(); 161 void item_tryingHosts(const StreamHostList &list); 162 void item_proxyConnect(); 163 void item_waitingForActivation(); 164 void item_connected(); 165 void item_error(int); 166 void query_finished(); 167 168 private: 169 class Private; 170 Private *d; 171 172 S5BConnection *findIncoming(const Jid &from, const QString &sid) const; 173 Entry *findEntry(S5BConnection *) const; 174 Entry *findEntry(Item *) const; 175 Entry *findEntryByHash(const QString &key) const; 176 Entry *findEntryBySID(const Jid &peer, const QString &sid) const; 177 Entry *findServerEntryByHash(const QString &key) const; 178 179 void entryContinue(Entry *e); 180 void queryProxy(Entry *e); 181 bool targetShouldOfferProxy(Entry *e); 182 183 friend class S5BConnection; 184 void con_connect(S5BConnection *); 185 void con_accept(S5BConnection *); 186 void con_reject(S5BConnection *); 187 void con_unlink(S5BConnection *); 188 void con_sendUDP(S5BConnection *, const QByteArray &buf); 189 190 friend class S5BServer; 191 bool srv_ownsHash(const QString &key) const; 192 void srv_incomingReady(SocksClient *sc, const QString &key); 193 void srv_incomingUDP(bool init, const QHostAddress &addr, int port, const QString &key, const QByteArray &data); 194 void srv_unlink(); 195 196 friend class Item; 197 void doSuccess(const Jid &peer, const QString &id, const Jid &streamHost); 198 void doError(const Jid &peer, const QString &id, int, const QString &); 199 void doActivate(const Jid &peer, const QString &sid, const Jid &streamHost); 200 }; 201 202 class IRIS_EXPORT S5BConnector : public QObject 203 { 204 Q_OBJECT 205 public: 206 S5BConnector(QObject *parent=0); 207 ~S5BConnector() override; 208 209 void reset(); 210 void start(const Jid &self, const StreamHostList &hosts, const QString &key, bool udp, int timeout); 211 SocksClient *takeClient(); 212 SocksUDP *takeUDP(); 213 StreamHost streamHostUsed() const; 214 215 class Item; 216 217 signals: 218 void result(bool); 219 220 private slots: 221 void item_result(bool); 222 void t_timeout(); 223 224 private: 225 class Private; 226 Private *d; 227 228 friend class S5BManager; 229 void man_udpSuccess(const Jid &streamHost); 230 }; 231 232 // listens on a port for serving 233 class IRIS_EXPORT S5BServer : public QObject 234 { 235 Q_OBJECT 236 public: 237 S5BServer(QObject *par=0); 238 ~S5BServer() override; 239 240 bool isActive() const; 241 bool start(int port); 242 void stop(); 243 int port() const; 244 void setHostList(const QStringList &); 245 QStringList hostList() const; 246 247 class Item; 248 249 private slots: 250 void ss_incomingReady(); 251 void ss_incomingUDP(const QString &host, int port, const QHostAddress &addr, int sourcePort, const QByteArray &data); 252 void item_result(bool); 253 254 private: 255 class Private; 256 Private *d; 257 258 friend class S5BManager; 259 void link(S5BManager *); 260 void unlink(S5BManager *); 261 void unlinkAll(); 262 const QList<S5BManager*> & managerList() const; 263 void writeUDP(const QHostAddress &addr, int port, const QByteArray &data); 264 }; 265 266 class IRIS_EXPORT JT_S5B : public Task 267 { 268 Q_OBJECT 269 public: 270 JT_S5B(Task *); 271 ~JT_S5B() override; 272 273 void request(const Jid &to, const QString &sid, const StreamHostList &hosts, bool fast, bool udp=false); 274 void requestProxyInfo(const Jid &to); 275 void requestActivation(const Jid &to, const QString &sid, const Jid &target); 276 277 void onGo() override; 278 void onDisconnect() override; 279 bool take(const QDomElement &) override; 280 281 Jid streamHostUsed() const; 282 StreamHost proxyInfo() const; 283 284 private slots: 285 void t_timeout(); 286 287 private: 288 class Private; 289 Private *d; 290 }; 291 292 struct IRIS_EXPORT S5BRequest 293 { 294 Jid from; 295 QString id, sid; 296 StreamHostList hosts; 297 bool fast; 298 bool udp; 299 }; 300 class IRIS_EXPORT JT_PushS5B : public Task 301 { 302 Q_OBJECT 303 public: 304 JT_PushS5B(Task *); 305 ~JT_PushS5B() override; 306 307 int priority() const; 308 309 void respondSuccess(const Jid &to, const QString &id, const Jid &streamHost); 310 void respondError(const Jid &to, const QString &id, int code, const QString &str); 311 void sendUDPSuccess(const Jid &to, const QString &dstaddr); 312 void sendActivate(const Jid &to, const QString &sid, const Jid &streamHost); 313 314 bool take(const QDomElement &) override; 315 316 signals: 317 void incoming(const S5BRequest &req); 318 void incomingUDPSuccess(const Jid &from, const QString &dstaddr); 319 void incomingActivate(const Jid &from, const QString &sid, const Jid &streamHost); 320 }; 321 322 class IRIS_EXPORT StreamHost 323 { 324 public: 325 StreamHost(); 326 327 const Jid & jid() const; 328 const QString & host() const; 329 int port() const; 330 bool isProxy() const; 331 void setJid(const Jid &); 332 void setHost(const QString &); 333 void setPort(int); 334 void setIsProxy(bool); 335 336 private: 337 Jid j; 338 QString v_host; 339 int v_port; 340 bool proxy; 341 }; 342 } 343 344 #endif 345