QXmpp  Version:0.8.0
 All Classes Functions Variables Enumerations Enumerator Properties Groups
QXmppStun.h
1 /*
2  * Copyright (C) 2008-2014 The QXmpp developers
3  *
4  * Author:
5  * Jeremy LainĂ©
6  *
7  * Source:
8  * http://code.google.com/p/qxmpp
9  *
10  * This file is a part of QXmpp library.
11  *
12  * This library is free software; you can redistribute it and/or
13  * modify it under the terms of the GNU Lesser General Public
14  * License as published by the Free Software Foundation; either
15  * version 2.1 of the License, or (at your option) any later version.
16  *
17  * This library is distributed in the hope that it will be useful,
18  * but WITHOUT ANY WARRANTY; without even the implied warranty of
19  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20  * Lesser General Public License for more details.
21  *
22  */
23 
24 #ifndef QXMPPSTUN_H
25 #define QXMPPSTUN_H
26 
27 #include <QObject>
28 
29 #include "QXmppLogger.h"
30 #include "QXmppJingleIq.h"
31 
32 class QDataStream;
33 class QUdpSocket;
34 class QTimer;
35 
40 
41 class QXMPP_EXPORT QXmppStunMessage
42 {
43 public:
44  enum MethodType {
45  Binding = 0x1,
46  SharedSecret = 0x2,
47  Allocate = 0x3,
48  Refresh = 0x4,
49  Send = 0x6,
50  Data = 0x7,
51  CreatePermission = 0x8,
52  ChannelBind = 0x9,
53  };
54 
55  enum ClassType {
56  Request = 0x000,
57  Indication = 0x010,
58  Response = 0x100,
59  Error = 0x110,
60  };
61 
62  QXmppStunMessage();
63 
64  quint32 cookie() const;
65  void setCookie(quint32 cookie);
66 
67  QByteArray id() const;
68  void setId(const QByteArray &id);
69 
70  quint16 messageClass() const;
71  quint16 messageMethod() const;
72 
73  quint16 type() const;
74  void setType(quint16 type);
75 
76  // attributes
77 
78  quint32 changeRequest() const;
79  void setChangeRequest(quint32 changeRequest);
80 
81  quint16 channelNumber() const;
82  void setChannelNumber(quint16 channelNumber);
83 
84  QByteArray data() const;
85  void setData(const QByteArray &data);
86 
87  quint32 lifetime() const;
88  void setLifetime(quint32 changeRequest);
89 
90  QByteArray nonce() const;
91  void setNonce(const QByteArray &nonce);
92 
93  quint32 priority() const;
94  void setPriority(quint32 priority);
95 
96  QString realm() const;
97  void setRealm(const QString &realm);
98 
99  QByteArray reservationToken() const;
100  void setReservationToken(const QByteArray &reservationToken);
101 
102  quint8 requestedTransport() const;
103  void setRequestedTransport(quint8 requestedTransport);
104 
105  QString software() const;
106  void setSoftware(const QString &software);
107 
108  QString username() const;
109  void setUsername(const QString &username);
110 
111  QByteArray encode(const QByteArray &key = QByteArray(), bool addFingerprint = true) const;
112  bool decode(const QByteArray &buffer, const QByteArray &key = QByteArray(), QStringList *errors = 0);
113  QString toString() const;
114  static quint16 peekType(const QByteArray &buffer, quint32 &cookie, QByteArray &id);
115 
116  // attributes
117  int errorCode;
118  QString errorPhrase;
119  QByteArray iceControlling;
120  QByteArray iceControlled;
121  QHostAddress changedHost;
122  quint16 changedPort;
123  QHostAddress mappedHost;
124  quint16 mappedPort;
125  QHostAddress otherHost;
126  quint16 otherPort;
127  QHostAddress sourceHost;
128  quint16 sourcePort;
129  QHostAddress xorMappedHost;
130  quint16 xorMappedPort;
131  QHostAddress xorPeerHost;
132  quint16 xorPeerPort;
133  QHostAddress xorRelayedHost;
134  quint16 xorRelayedPort;
135  bool useCandidate;
136 
137 private:
138  quint32 m_cookie;
139  QByteArray m_id;
140  quint16 m_type;
141 
142  // attributes
143  QSet<quint16> m_attributes;
144  quint32 m_changeRequest;
145  quint16 m_channelNumber;
146  QByteArray m_data;
147  quint32 m_lifetime;
148  QByteArray m_nonce;
149  quint32 m_priority;
150  QString m_realm;
151  quint8 m_requestedTransport;
152  QByteArray m_reservationToken;
153  QString m_software;
154  QString m_username;
155 };
156 
161 
162 class QXMPP_EXPORT QXmppStunTransaction : public QXmppLoggable
163 {
164  Q_OBJECT
165 
166 public:
167  QXmppStunTransaction(const QXmppStunMessage &request, QObject *parent);
168  QXmppStunMessage request() const;
169  QXmppStunMessage response() const;
170 
171 signals:
172  void finished();
173  void writeStun(const QXmppStunMessage &request);
174 
175 public slots:
176  void readStun(const QXmppStunMessage &response);
177 
178 private slots:
179  void retry();
180 
181 private:
182  QXmppStunMessage m_request;
183  QXmppStunMessage m_response;
184  QTimer *m_retryTimer;
185  int m_tries;
186 };
187 
193 
194 class QXMPP_EXPORT QXmppTurnAllocation : public QXmppLoggable
195 {
196  Q_OBJECT
197 
198 public:
199  enum AllocationState
200  {
201  UnconnectedState,
202  ConnectingState,
203  ConnectedState,
204  ClosingState,
205  };
206 
207  QXmppTurnAllocation(QObject *parent = 0);
208  ~QXmppTurnAllocation();
209 
210  QHostAddress relayedHost() const;
211  quint16 relayedPort() const;
212  AllocationState state() const;
213 
214  void setServer(const QHostAddress &host, quint16 port = 3478);
215  void setUser(const QString &user);
216  void setPassword(const QString &password);
217 
218  qint64 writeDatagram(const QByteArray &data, const QHostAddress &host, quint16 port);
219 
220 signals:
222  void connected();
223 
225  void datagramReceived(const QByteArray &data, const QHostAddress &host, quint16 port);
226 
228  void disconnected();
229 
230 public slots:
231  void connectToHost();
232  void disconnectFromHost();
233 
234 private slots:
235  void readyRead();
236  void refresh();
237  void refreshChannels();
238  void transactionFinished();
239  void writeStun(const QXmppStunMessage &message);
240 
241 private:
242  void handleDatagram(const QByteArray &datagram, const QHostAddress &host, quint16 port);
243  void setState(AllocationState state);
244 
245  QUdpSocket *socket;
246  QTimer *m_timer;
247  QTimer *m_channelTimer;
248  QString m_password;
249  QString m_username;
250  QHostAddress m_relayedHost;
251  quint16 m_relayedPort;
252  QHostAddress m_turnHost;
253  quint16 m_turnPort;
254 
255  // channels
256  typedef QPair<QHostAddress, quint16> Address;
257  quint16 m_channelNumber;
258  QMap<quint16, Address> m_channels;
259 
260  // state
261  quint32 m_lifetime;
262  QByteArray m_key;
263  QString m_realm;
264  QByteArray m_nonce;
265  AllocationState m_state;
266  QList<QXmppStunTransaction*> m_transactions;
267 };
268 
272 
273 class QXMPP_EXPORT QXmppIceComponent : public QXmppLoggable
274 {
275  Q_OBJECT
276 
277 public:
278  QXmppIceComponent(QObject *parent=0);
280  void setIceControlling(bool controlling);
281  void setStunServer(const QHostAddress &host, quint16 port);
282  void setTurnServer(const QHostAddress &host, quint16 port);
283  void setTurnUser(const QString &user);
284  void setTurnPassword(const QString &password);
285 
286  QList<QXmppJingleCandidate> localCandidates() const;
287  void setLocalUser(const QString &user);
288  void setLocalPassword(const QString &password);
289 
290  int component() const;
291  void setComponent(int component);
292 
293  bool addRemoteCandidate(const QXmppJingleCandidate &candidate);
294  void setRemoteUser(const QString &user);
295  void setRemotePassword(const QString &password);
296 
297  bool isConnected() const;
298  void setSockets(QList<QUdpSocket*> sockets);
299 
300  static QList<QHostAddress> discoverAddresses();
301  static QList<QUdpSocket*> reservePorts(const QList<QHostAddress> &addresses, int count, QObject *parent = 0);
302 
303 public slots:
304  void close();
305  void connectToHost();
306  qint64 sendDatagram(const QByteArray &datagram);
307 
308 private slots:
309  void checkCandidates();
310  void checkStun();
311  void handleDatagram(const QByteArray &datagram, const QHostAddress &host, quint16 port, QUdpSocket *socket = 0);
312  void readyRead();
313  void turnConnected();
314 
315 signals:
317  void connected();
318 
320  void datagramReceived(const QByteArray &datagram);
321 
323  void localCandidatesChanged();
324 
325 private:
326  class Pair {
327  public:
328  Pair(int component, bool controlling);
329  quint64 priority() const;
330  QString toString() const;
331 
332  QIODevice::OpenMode checked;
333  QXmppJingleCandidate remote;
334  QXmppJingleCandidate reflexive;
335  QByteArray transaction;
336  QUdpSocket *socket;
337 
338  private:
339  int m_component;
340  bool m_controlling;
341  };
342 
343  Pair *addRemoteCandidate(QUdpSocket *socket, const QHostAddress &host, quint16 port, quint32 priority);
344  qint64 writeStun(const QXmppStunMessage &message, QXmppIceComponent::Pair *pair);
345 
346  int m_component;
347 
348  QList<QXmppJingleCandidate> m_localCandidates;
349  QString m_localUser;
350  QString m_localPassword;
351 
352  Pair *m_activePair;
353  Pair *m_fallbackPair;
354  bool m_iceControlling;
355  QList<Pair*> m_pairs;
356  quint32 m_peerReflexivePriority;
357  QString m_remoteUser;
358  QString m_remotePassword;
359 
360  QList<QUdpSocket*> m_sockets;
361  QTimer *m_timer;
362 
363  // STUN server
364  QByteArray m_stunId;
365  QHostAddress m_stunHost;
366  quint16 m_stunPort;
367  QTimer *m_stunTimer;
368  int m_stunTries;
369 
370  // TURN server
371  QXmppTurnAllocation *m_turnAllocation;
372  bool m_turnConfigured;
373 };
374 
378 
379 class QXMPP_EXPORT QXmppIceConnection : public QXmppLoggable
380 {
381  Q_OBJECT
382 
383 public:
384  QXmppIceConnection(QObject *parent = 0);
385 
386  QXmppIceComponent *component(int component);
387  void addComponent(int component);
388  void setIceControlling(bool controlling);
389 
390  QList<QXmppJingleCandidate> localCandidates() const;
391  QString localUser() const;
392  void setLocalUser(const QString &user);
393  QString localPassword() const;
394  void setLocalPassword(const QString &password);
395 
396  void addRemoteCandidate(const QXmppJingleCandidate &candidate);
397  void setRemoteUser(const QString &user);
398  void setRemotePassword(const QString &password);
399 
400  void setStunServer(const QHostAddress &host, quint16 port = 3478);
401  void setTurnServer(const QHostAddress &host, quint16 port = 3478);
402  void setTurnUser(const QString &user);
403  void setTurnPassword(const QString &password);
404 
405  bool bind(const QList<QHostAddress> &addresses);
406  bool isConnected() const;
407 
408 signals:
410  void connected();
411 
413  void disconnected();
414 
416  void localCandidatesChanged();
417 
418 public slots:
419  void close();
420  void connectToHost();
421 
422 private slots:
423  void slotConnected();
424  void slotTimeout();
425 
426 private:
427  QTimer *m_connectTimer;
428  bool m_iceControlling;
429  QMap<int, QXmppIceComponent*> m_components;
430  QString m_localUser;
431  QString m_localPassword;
432  QHostAddress m_stunHost;
433  quint16 m_stunPort;
434  QHostAddress m_turnHost;
435  quint16 m_turnPort;
436  QString m_turnUser;
437  QString m_turnPassword;
438 };
439 
440 #endif