QXmpp Version:0.3.91
|
00001 /* 00002 * Copyright (C) 2008-2011 The QXmpp developers 00003 * 00004 * Author: 00005 * Jeremy Lainé 00006 * 00007 * Source: 00008 * http://code.google.com/p/qxmpp 00009 * 00010 * This file is a part of QXmpp library. 00011 * 00012 * This library is free software; you can redistribute it and/or 00013 * modify it under the terms of the GNU Lesser General Public 00014 * License as published by the Free Software Foundation; either 00015 * version 2.1 of the License, or (at your option) any later version. 00016 * 00017 * This library is distributed in the hope that it will be useful, 00018 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00019 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00020 * Lesser General Public License for more details. 00021 * 00022 */ 00023 00024 #ifndef QXMPPSTUN_H 00025 #define QXMPPSTUN_H 00026 00027 #include <QObject> 00028 00029 #include "QXmppLogger.h" 00030 #include "QXmppJingleIq.h" 00031 00032 class QDataStream; 00033 class QUdpSocket; 00034 class QTimer; 00035 00040 00041 class QXmppStunMessage 00042 { 00043 public: 00044 enum MethodType { 00045 Binding = 0x1, 00046 SharedSecret = 0x2, 00047 Allocate = 0x3, 00048 Refresh = 0x4, 00049 Send = 0x6, 00050 Data = 0x7, 00051 CreatePermission = 0x8, 00052 ChannelBind = 0x9, 00053 }; 00054 00055 enum ClassType { 00056 Request = 0x000, 00057 Indication = 0x010, 00058 Response = 0x100, 00059 Error = 0x110, 00060 }; 00061 00062 QXmppStunMessage(); 00063 00064 quint32 cookie() const; 00065 void setCookie(quint32 cookie); 00066 00067 QByteArray id() const; 00068 void setId(const QByteArray &id); 00069 00070 quint16 messageClass() const; 00071 quint16 messageMethod() const; 00072 00073 quint16 type() const; 00074 void setType(quint16 type); 00075 00076 // attributes 00077 00078 quint32 changeRequest() const; 00079 void setChangeRequest(quint32 changeRequest); 00080 00081 quint16 channelNumber() const; 00082 void setChannelNumber(quint16 channelNumber); 00083 00084 QByteArray data() const; 00085 void setData(const QByteArray &data); 00086 00087 quint32 lifetime() const; 00088 void setLifetime(quint32 changeRequest); 00089 00090 QByteArray nonce() const; 00091 void setNonce(const QByteArray &nonce); 00092 00093 quint32 priority() const; 00094 void setPriority(quint32 priority); 00095 00096 QString realm() const; 00097 void setRealm(const QString &realm); 00098 00099 QByteArray reservationToken() const; 00100 void setReservationToken(const QByteArray &reservationToken); 00101 00102 quint8 requestedTransport() const; 00103 void setRequestedTransport(quint8 requestedTransport); 00104 00105 QString software() const; 00106 void setSoftware(const QString &software); 00107 00108 QString username() const; 00109 void setUsername(const QString &username); 00110 00111 QByteArray encode(const QByteArray &key = QByteArray(), bool addFingerprint = true) const; 00112 bool decode(const QByteArray &buffer, const QByteArray &key = QByteArray(), QStringList *errors = 0); 00113 QString toString() const; 00114 static quint16 peekType(const QByteArray &buffer, quint32 &cookie, QByteArray &id); 00115 00116 // attributes 00117 int errorCode; 00118 QString errorPhrase; 00119 QByteArray iceControlling; 00120 QByteArray iceControlled; 00121 QHostAddress changedHost; 00122 quint16 changedPort; 00123 QHostAddress mappedHost; 00124 quint16 mappedPort; 00125 QHostAddress otherHost; 00126 quint16 otherPort; 00127 QHostAddress sourceHost; 00128 quint16 sourcePort; 00129 QHostAddress xorMappedHost; 00130 quint16 xorMappedPort; 00131 QHostAddress xorPeerHost; 00132 quint16 xorPeerPort; 00133 QHostAddress xorRelayedHost; 00134 quint16 xorRelayedPort; 00135 bool useCandidate; 00136 00137 private: 00138 quint32 m_cookie; 00139 QByteArray m_id; 00140 quint16 m_type; 00141 00142 // attributes 00143 QSet<quint16> m_attributes; 00144 quint32 m_changeRequest; 00145 quint16 m_channelNumber; 00146 QByteArray m_data; 00147 quint32 m_lifetime; 00148 QByteArray m_nonce; 00149 quint32 m_priority; 00150 QString m_realm; 00151 quint8 m_requestedTransport; 00152 QByteArray m_reservationToken; 00153 QString m_software; 00154 QString m_username; 00155 }; 00156 00161 00162 class QXmppStunTransaction : public QXmppLoggable 00163 { 00164 Q_OBJECT 00165 00166 public: 00167 QXmppStunTransaction(const QXmppStunMessage &request, QObject *parent); 00168 QXmppStunMessage request() const; 00169 QXmppStunMessage response() const; 00170 00171 signals: 00172 void finished(); 00173 void writeStun(const QXmppStunMessage &request); 00174 00175 public slots: 00176 void readStun(const QXmppStunMessage &response); 00177 00178 private slots: 00179 void retry(); 00180 00181 private: 00182 QXmppStunMessage m_request; 00183 QXmppStunMessage m_response; 00184 QTimer *m_retryTimer; 00185 int m_tries; 00186 }; 00187 00193 00194 class QXmppTurnAllocation : public QXmppLoggable 00195 { 00196 Q_OBJECT 00197 00198 public: 00199 enum AllocationState 00200 { 00201 UnconnectedState, 00202 ConnectingState, 00203 ConnectedState, 00204 ClosingState, 00205 }; 00206 00207 QXmppTurnAllocation(QObject *parent = 0); 00208 ~QXmppTurnAllocation(); 00209 00210 QHostAddress relayedHost() const; 00211 quint16 relayedPort() const; 00212 AllocationState state() const; 00213 00214 void setServer(const QHostAddress &host, quint16 port = 3478); 00215 void setUser(const QString &user); 00216 void setPassword(const QString &password); 00217 00218 qint64 writeDatagram(const QByteArray &data, const QHostAddress &host, quint16 port); 00219 00220 signals: 00222 void connected(); 00223 00225 void datagramReceived(const QByteArray &data, const QHostAddress &host, quint16 port); 00226 00228 void disconnected(); 00229 00230 public slots: 00231 void connectToHost(); 00232 void disconnectFromHost(); 00233 00234 private slots: 00235 void readyRead(); 00236 void refresh(); 00237 void refreshChannels(); 00238 void transactionFinished(); 00239 void writeStun(const QXmppStunMessage &message); 00240 00241 private: 00242 void handleDatagram(const QByteArray &datagram, const QHostAddress &host, quint16 port); 00243 void setState(AllocationState state); 00244 00245 QUdpSocket *socket; 00246 QTimer *m_timer; 00247 QTimer *m_channelTimer; 00248 QString m_password; 00249 QString m_username; 00250 QHostAddress m_relayedHost; 00251 quint16 m_relayedPort; 00252 QHostAddress m_turnHost; 00253 quint16 m_turnPort; 00254 00255 // channels 00256 typedef QPair<QHostAddress, quint16> Address; 00257 quint16 m_channelNumber; 00258 QMap<quint16, Address> m_channels; 00259 00260 // state 00261 quint32 m_lifetime; 00262 QByteArray m_key; 00263 QString m_realm; 00264 QByteArray m_nonce; 00265 AllocationState m_state; 00266 QList<QXmppStunTransaction*> m_transactions; 00267 }; 00268 00272 00273 class QXmppIceComponent : public QXmppLoggable 00274 { 00275 Q_OBJECT 00276 00277 public: 00278 QXmppIceComponent(QObject *parent=0); 00279 ~QXmppIceComponent(); 00280 void setIceControlling(bool controlling); 00281 void setStunServer(const QHostAddress &host, quint16 port); 00282 void setTurnServer(const QHostAddress &host, quint16 port); 00283 void setTurnUser(const QString &user); 00284 void setTurnPassword(const QString &password); 00285 00286 QList<QXmppJingleCandidate> localCandidates() const; 00287 void setLocalUser(const QString &user); 00288 void setLocalPassword(const QString &password); 00289 00290 int component() const; 00291 void setComponent(int component); 00292 00293 bool addRemoteCandidate(const QXmppJingleCandidate &candidate); 00294 void setRemoteUser(const QString &user); 00295 void setRemotePassword(const QString &password); 00296 00297 bool isConnected() const; 00298 void setSockets(QList<QUdpSocket*> sockets); 00299 00300 static QList<QHostAddress> discoverAddresses(); 00301 static QList<QUdpSocket*> reservePorts(const QList<QHostAddress> &addresses, int count, QObject *parent = 0); 00302 00303 public slots: 00304 void close(); 00305 void connectToHost(); 00306 qint64 sendDatagram(const QByteArray &datagram); 00307 00308 private slots: 00309 void checkCandidates(); 00310 void checkStun(); 00311 void handleDatagram(const QByteArray &datagram, const QHostAddress &host, quint16 port, QUdpSocket *socket = 0); 00312 void readyRead(); 00313 void turnConnected(); 00314 00315 signals: 00317 void connected(); 00318 00320 void datagramReceived(const QByteArray &datagram); 00321 00323 void localCandidatesChanged(); 00324 00325 private: 00326 class Pair { 00327 public: 00328 Pair(int component, bool controlling); 00329 quint64 priority() const; 00330 QString toString() const; 00331 00332 QIODevice::OpenMode checked; 00333 QXmppJingleCandidate remote; 00334 QXmppJingleCandidate reflexive; 00335 QByteArray transaction; 00336 QUdpSocket *socket; 00337 00338 private: 00339 int m_component; 00340 bool m_controlling; 00341 }; 00342 00343 Pair *addRemoteCandidate(QUdpSocket *socket, const QHostAddress &host, quint16 port, quint32 priority); 00344 qint64 writeStun(const QXmppStunMessage &message, QXmppIceComponent::Pair *pair); 00345 00346 int m_component; 00347 00348 QList<QXmppJingleCandidate> m_localCandidates; 00349 QString m_localUser; 00350 QString m_localPassword; 00351 00352 Pair *m_activePair; 00353 Pair *m_fallbackPair; 00354 bool m_iceControlling; 00355 QList<Pair*> m_pairs; 00356 quint32 m_peerReflexivePriority; 00357 QString m_remoteUser; 00358 QString m_remotePassword; 00359 00360 QList<QUdpSocket*> m_sockets; 00361 QTimer *m_timer; 00362 00363 // STUN server 00364 QByteArray m_stunId; 00365 QHostAddress m_stunHost; 00366 quint16 m_stunPort; 00367 QTimer *m_stunTimer; 00368 int m_stunTries; 00369 00370 // TURN server 00371 QXmppTurnAllocation *m_turnAllocation; 00372 bool m_turnConfigured; 00373 }; 00374 00378 00379 class QXmppIceConnection : public QXmppLoggable 00380 { 00381 Q_OBJECT 00382 00383 public: 00384 QXmppIceConnection(QObject *parent = 0); 00385 00386 QXmppIceComponent *component(int component); 00387 void addComponent(int component); 00388 void setIceControlling(bool controlling); 00389 00390 QList<QXmppJingleCandidate> localCandidates() const; 00391 QString localUser() const; 00392 void setLocalUser(const QString &user); 00393 QString localPassword() const; 00394 void setLocalPassword(const QString &password); 00395 00396 void addRemoteCandidate(const QXmppJingleCandidate &candidate); 00397 void setRemoteUser(const QString &user); 00398 void setRemotePassword(const QString &password); 00399 00400 void setStunServer(const QHostAddress &host, quint16 port = 3478); 00401 void setTurnServer(const QHostAddress &host, quint16 port = 3478); 00402 void setTurnUser(const QString &user); 00403 void setTurnPassword(const QString &password); 00404 00405 bool bind(const QList<QHostAddress> &addresses); 00406 bool isConnected() const; 00407 00408 signals: 00410 void connected(); 00411 00413 void disconnected(); 00414 00416 void localCandidatesChanged(); 00417 00418 public slots: 00419 void close(); 00420 void connectToHost(); 00421 00422 private slots: 00423 void slotConnected(); 00424 void slotTimeout(); 00425 00426 private: 00427 QTimer *m_connectTimer; 00428 bool m_iceControlling; 00429 QMap<int, QXmppIceComponent*> m_components; 00430 QString m_localUser; 00431 QString m_localPassword; 00432 QHostAddress m_stunHost; 00433 quint16 m_stunPort; 00434 QHostAddress m_turnHost; 00435 quint16 m_turnPort; 00436 QString m_turnUser; 00437 QString m_turnPassword; 00438 }; 00439 00440 #endif