00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
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 };
00049
00050 enum MessageType {
00051 Request = 0x000,
00052 Indication = 0x010,
00053 Response = 0x100,
00054 Error = 0x110,
00055 };
00056
00057 QXmppStunMessage();
00058
00059 quint32 cookie() const;
00060 void setCookie(quint32 cookie);
00061
00062 QByteArray id() const;
00063 void setId(const QByteArray &id);
00064
00065 quint16 type() const;
00066 void setType(quint16 type);
00067
00068
00069
00070 quint32 changeRequest() const;
00071 void setChangeRequest(quint32 changeRequest);
00072
00073 quint32 priority() const;
00074 void setPriority(quint32 priority);
00075
00076 QString software() const;
00077 void setSoftware(const QString &software);
00078
00079 QByteArray encode(const QString &password = QString(), bool addFingerprint = true) const;
00080 bool decode(const QByteArray &buffer, const QString &password = QString(), QStringList *errors = 0);
00081 QString toString() const;
00082 static quint16 peekType(const QByteArray &buffer, quint32 &cookie, QByteArray &id);
00083
00084
00085 int errorCode;
00086 QString errorPhrase;
00087 QByteArray iceControlling;
00088 QByteArray iceControlled;
00089 QHostAddress changedHost;
00090 quint16 changedPort;
00091 QHostAddress mappedHost;
00092 quint16 mappedPort;
00093 QHostAddress otherHost;
00094 quint16 otherPort;
00095 QHostAddress sourceHost;
00096 quint16 sourcePort;
00097 QHostAddress xorMappedHost;
00098 quint16 xorMappedPort;
00099 QString username;
00100 bool useCandidate;
00101
00102 private:
00103 quint32 m_cookie;
00104 QByteArray m_id;
00105 quint16 m_type;
00106
00107 QSet<quint16> m_attributes;
00108 quint32 m_changeRequest;
00109 quint32 m_priority;
00110 QString m_software;
00111 };
00112
00116
00117 class QXmppIceComponent : public QXmppLoggable
00118 {
00119 Q_OBJECT
00120
00121 public:
00122 QXmppIceComponent(bool controlling, QObject *parent=0);
00123 ~QXmppIceComponent();
00124 void setStunServer(const QHostAddress &host, quint16 port);
00125
00126 QList<QXmppJingleCandidate> localCandidates() const;
00127 void setLocalUser(const QString &user);
00128 void setLocalPassword(const QString &password);
00129
00130 int component() const;
00131 void setComponent(int component);
00132
00133 bool addRemoteCandidate(const QXmppJingleCandidate &candidate);
00134 void setRemoteUser(const QString &user);
00135 void setRemotePassword(const QString &password);
00136
00137 bool isConnected() const;
00138 void setSockets(QList<QUdpSocket*> sockets);
00139
00140 static QList<QHostAddress> discoverAddresses();
00141 static QList<QUdpSocket*> reservePorts(const QList<QHostAddress> &addresses, int count, QObject *parent = 0);
00142
00143 public slots:
00144 void close();
00145 void connectToHost();
00146 qint64 sendDatagram(const QByteArray &datagram);
00147
00148 private slots:
00149 void checkCandidates();
00150 void checkStun();
00151 void readyRead();
00152
00153 signals:
00155 void connected();
00156
00158 void datagramReceived(const QByteArray &datagram);
00159
00161 void localCandidatesChanged();
00162
00163 private:
00164 class Pair {
00165 public:
00166 Pair();
00167 QString toString() const;
00168
00169 QIODevice::OpenMode checked;
00170 quint32 priority;
00171 QXmppJingleCandidate remote;
00172 QXmppJingleCandidate reflexive;
00173 QByteArray transaction;
00174 QUdpSocket *socket;
00175 };
00176
00177 Pair *addRemoteCandidate(QUdpSocket *socket, const QHostAddress &host, quint16 port);
00178 qint64 writeStun(const QXmppStunMessage &message, QXmppIceComponent::Pair *pair);
00179
00180 int m_component;
00181
00182 QList<QXmppJingleCandidate> m_localCandidates;
00183 QString m_localUser;
00184 QString m_localPassword;
00185
00186 Pair *m_activePair;
00187 Pair *m_fallbackPair;
00188 bool m_iceControlling;
00189 QList<Pair*> m_pairs;
00190 QString m_remoteUser;
00191 QString m_remotePassword;
00192
00193 QList<QUdpSocket*> m_sockets;
00194 QTimer *m_timer;
00195
00196
00197 QByteArray m_stunId;
00198 QHostAddress m_stunHost;
00199 quint16 m_stunPort;
00200 QTimer *m_stunTimer;
00201 int m_stunTries;
00202 };
00203
00207
00208 class QXmppIceConnection : public QXmppLoggable
00209 {
00210 Q_OBJECT
00211
00212 public:
00213 QXmppIceConnection(bool controlling, QObject *parent = 0);
00214
00215 QXmppIceComponent *component(int component);
00216 void addComponent(int component);
00217
00218 QList<QXmppJingleCandidate> localCandidates() const;
00219 QString localUser() const;
00220 QString localPassword() const;
00221
00222 void addRemoteCandidate(const QXmppJingleCandidate &candidate);
00223 void setRemoteUser(const QString &user);
00224 void setRemotePassword(const QString &password);
00225
00226 void setStunServer(const QHostAddress &host, quint16 port = 3478);
00227
00228 bool bind(const QList<QHostAddress> &addresses);
00229 bool isConnected() const;
00230
00231 signals:
00233 void connected();
00234
00236 void disconnected();
00237
00239 void localCandidatesChanged();
00240
00241 public slots:
00242 void close();
00243 void connectToHost();
00244
00245 private slots:
00246 void slotConnected();
00247 void slotTimeout();
00248
00249 private:
00250 QTimer *m_connectTimer;
00251 bool m_controlling;
00252 QMap<int, QXmppIceComponent*> m_components;
00253 QString m_localUser;
00254 QString m_localPassword;
00255 QHostAddress m_stunHost;
00256 quint16 m_stunPort;
00257 };
00258
00259 #endif