QXmpp Version:0.3.91
QXmppStun.h
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
 All Classes Functions Enumerations Enumerator Properties