1 /* 2 * Copyright (C) 2010 Barracuda Networks, Inc. 3 * 4 * This library is free software; you can redistribute it and/or 5 * modify it under the terms of the GNU Lesser General Public 6 * License as published by the Free Software Foundation; either 7 * version 2.1 of the License, or (at your option) any later version. 8 * 9 * This library is distributed in the hope that it will be useful, 10 * but WITHANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 * Lesser General Public License for more details. 13 * 14 * You should have received a copy of the GNU Lesser General Public 15 * License along with this library; if not, write to the Free Software 16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 17 * 02110-1301 USA 18 * 19 */ 20 21 #ifndef TURNCLIENT_H 22 #define TURNCLIENT_H 23 24 #include <QObject> 25 #include <QByteArray> 26 #include <QString> 27 #include <QHostAddress> 28 29 namespace QCA { 30 class SecureArray; 31 } 32 33 namespace XMPP { 34 35 class StunTransactionPool; 36 class StunAllocate; 37 38 class TurnClient : public QObject 39 { 40 Q_OBJECT 41 42 public: 43 enum Error 44 { 45 ErrorGeneric, 46 ErrorHostNotFound, 47 ErrorConnect, 48 49 // stream error or stream unexpectedly disconnected by peer 50 ErrorStream, 51 52 ErrorProxyConnect, 53 ErrorProxyNeg, 54 ErrorProxyAuth, 55 ErrorTls, 56 ErrorAuth, 57 ErrorRejected, 58 ErrorProtocol, 59 ErrorCapacity, 60 61 // according to the TURN spec, a client should try three times 62 // to correct a mismatch error before giving up. this class 63 // will perform the retries internally, and ErrorMismatch is 64 // only emitted when it has given up. note that if this 65 // happens, the TURN spec says you should not connect to the 66 // TURN server again for at least 2 minutes. 67 // note: in UDP mode, this class does not perform retries and 68 // will emit this error immediately. 69 ErrorMismatch 70 }; 71 72 enum Mode 73 { 74 PlainMode, 75 TlsMode 76 }; 77 78 enum DebugLevel 79 { 80 DL_None, 81 DL_Info, 82 DL_Packet 83 }; 84 85 // adapted from XMPP::AdvancedConnector 86 class Proxy 87 { 88 public: 89 enum 90 { 91 None, 92 HttpConnect, 93 Socks 94 }; 95 96 Proxy(); 97 ~Proxy(); 98 99 int type() const; 100 QString host() const; 101 quint16 port() const; 102 QString user() const; 103 QString pass() const; 104 105 void setHttpConnect(const QString &host, quint16 port); 106 void setSocks(const QString &host, quint16 port); 107 void setUserPass(const QString &user, const QString &pass); 108 109 private: 110 int t; 111 QString v_host; 112 quint16 v_port; 113 QString v_user, v_pass; 114 }; 115 116 TurnClient(QObject *parent = 0); 117 ~TurnClient(); 118 119 void setProxy(const Proxy &proxy); 120 void setClientSoftwareNameAndVersion(const QString &str); 121 122 // for UDP. does not take ownership of the pool. stun transaction 123 // I/O occurs through the pool. transfer of data packets occurs 124 // via processIncomingDatagram(), outgoingDatagram(), and 125 // outgoingDatagramsWritten(). authentication happens through the 126 // pool and not through this class. the turn addr/port is optional, 127 // and used only for addr association with the pool 128 void connectToHost(StunTransactionPool *pool, const QHostAddress &addr = QHostAddress(), int port = -1); 129 130 // for TCP and TCP-TLS 131 void connectToHost(const QHostAddress &addr, int port, Mode mode = PlainMode); 132 133 // for UDP, use this function to process incoming packets instead of 134 // read(). 135 QByteArray processIncomingDatagram(const QByteArray &buf, bool notStun, QHostAddress *addr, int *port); 136 137 // call after writing datagrams from outgoingDatagram. not DOR-DS safe 138 void outgoingDatagramsWritten(int count); 139 140 QString realm() const; 141 void setUsername(const QString &username); 142 void setPassword(const QCA::SecureArray &password); 143 void setRealm(const QString &realm); 144 void continueAfterParams(); 145 146 void close(); 147 148 StunAllocate *stunAllocate(); 149 150 void addChannelPeer(const QHostAddress &addr, int port); 151 152 int packetsToRead() const; 153 int packetsToWrite() const; 154 155 // TCP mode only 156 QByteArray read(QHostAddress *addr, int *port); 157 158 // for UDP, this call may emit outgoingDatagram() immediately (not 159 // DOR-DS safe) 160 void write(const QByteArray &buf, const QHostAddress &addr, int port); 161 162 QString errorString() const; 163 164 void setDebugLevel(DebugLevel level); // default DL_None 165 166 signals: 167 void connected(); // tcp connected 168 void tlsHandshaken(); 169 void closed(); 170 void needAuthParams(); 171 void retrying(); // mismatch error received, starting all over 172 void activated(); // ready for read/write 173 174 // TCP mode only 175 void readyRead(); 176 177 void packetsWritten(int count, const QHostAddress &addr, int port); 178 void error(XMPP::TurnClient::Error e); 179 180 // data packets to be sent to the TURN server, UDP mode only 181 void outgoingDatagram(const QByteArray &buf); 182 183 // not DOR-SS/DS safe 184 void debugLine(const QString &line); 185 186 private: 187 class Private; 188 friend class Private; 189 Private *d; 190 }; 191 192 } 193 194 #endif 195