1 // Copyright 2005-2019 The Mumble Developers. All rights reserved.
2 // Use of this source code is governed by a BSD-style license
3 // that can be found in the LICENSE file at the root of the
4 // Mumble source tree or at <https://www.mumble.info/LICENSE>.
5 
6 #ifndef MUMBLE_MUMBLE_SERVERHANDLER_H_
7 #define MUMBLE_MUMBLE_SERVERHANDLER_H_
8 
9 #ifndef Q_MOC_RUN
10 # include <boost/accumulators/accumulators.hpp>
11 # include <boost/accumulators/statistics/stats.hpp>
12 # include <boost/accumulators/statistics/mean.hpp>
13 # include <boost/accumulators/statistics/variance.hpp>
14 # include <boost/shared_ptr.hpp>
15 #endif
16 
17 #include <QtCore/QEvent>
18 #include <QtCore/QMutex>
19 #include <QtCore/QObject>
20 #include <QtCore/QThread>
21 #include <QtCore/QTimer>
22 #include <QtNetwork/QHostAddress>
23 #include <QtNetwork/QSslCipher>
24 #include <QtNetwork/QSslError>
25 
26 #ifdef Q_OS_WIN
27 #include <windows.h>
28 #endif
29 
30 #define SERVERSEND_EVENT 3501
31 
32 #include "Timer.h"
33 #include "Message.h"
34 #include "Mumble.pb.h"
35 #include "ServerAddress.h"
36 
37 class Connection;
38 class Database;
39 class Message;
40 class PacketDataStream;
41 class QUdpSocket;
42 class QSslSocket;
43 class VoiceRecorder;
44 
45 class ServerHandlerMessageEvent : public QEvent {
46 	public:
47 		unsigned int uiType;
48 		QByteArray qbaMsg;
49 		bool bFlush;
50 		ServerHandlerMessageEvent(const QByteArray &msg, unsigned int type, bool flush = false);
51 };
52 
53 typedef boost::shared_ptr<Connection> ConnectionPtr;
54 
55 class ServerHandler : public QThread {
56 	private:
57 		Q_OBJECT
58 		Q_DISABLE_COPY(ServerHandler)
59 
60 		Database *database;
61 	protected:
62 		QString qsHostName;
63 		QString qsUserName;
64 		QString qsPassword;
65 		unsigned short usPort;
66 		unsigned short usResolvedPort;
67 		bool bUdp;
68 		bool bStrong;
69 
70 		/// Flag indicating whether the server we are currently connected to has
71 		/// finsihed synchronizing already.
72 		bool serverSyncronized = false;
73 
74 #ifdef Q_OS_WIN
75 		HANDLE hQoS;
76 		DWORD dwFlowUDP;
77 #endif
78 
79 		QHostAddress qhaRemote;
80 		QHostAddress qhaLocal;
81 		QUdpSocket *qusUdp;
82 		QMutex qmUdp;
83 
84 		void handleVoicePacket(unsigned int msgFlags, PacketDataStream &pds, MessageHandler::UDPMessageType type);
85 	public:
86 		Timer tTimestamp;
87 		int iInFlightTCPPings;
88 		QTimer *tConnectionTimeoutTimer;
89 		QList<QSslError> qlErrors;
90 		QList<QSslCertificate> qscCert;
91 		QSslCipher qscCipher;
92 		ConnectionPtr cConnection;
93 		QByteArray qbaDigest;
94 		boost::shared_ptr<VoiceRecorder> recorder;
95 		QSslSocket *qtsSock;
96 		QList<ServerAddress> qlAddresses;
97 		ServerAddress saTargetServer;
98 
99 		unsigned int uiVersion;
100 		QString qsRelease;
101 		QString qsOS;
102 		QString qsOSVersion;
103 
104 		boost::accumulators::accumulator_set<double, boost::accumulators::stats<boost::accumulators::tag::mean, boost::accumulators::tag::variance, boost::accumulators::tag::count> > accTCP, accUDP, accClean;
105 
106 		ServerHandler();
107 		~ServerHandler();
108 		void setConnectionInfo(const QString &host, unsigned short port, const QString &username, const QString &pw);
109 		void getConnectionInfo(QString &host, unsigned short &port, QString &username, QString &pw) const;
110 		bool isStrong() const;
111 		void customEvent(QEvent *evt) Q_DECL_OVERRIDE;
112 
113 		void sendProtoMessage(const ::google::protobuf::Message &msg, unsigned int msgType);
114 		void sendMessage(const char *data, int len, bool force = false);
115 
116 		/// @returns Whether this handler is currently connected to a server.
117 		bool isConnected() const;
118 
119 		/// @returns Whether the server this handler is currently connected to, has finished
120 		/// 	synchronizing yet.
121 		bool hasSynchronized() const;
122 
123 		/// @param synchronized Whether the server has finished synchronization
124 		void setServerSynchronized(bool synchronized);
125 
126 #define MUMBLE_MH_MSG(x) void sendMessage(const MumbleProto:: x &msg) { sendProtoMessage(msg, MessageHandler:: x); }
127 		MUMBLE_MH_ALL
128 #undef MUMBLE_MH_MSG
129 
130 		void requestUserStats(unsigned int uiSession, bool statsOnly);
131 		void joinChannel(unsigned int uiSession, unsigned int channel);
132 		void createChannel(unsigned int parent_id, const QString &name, const QString &description, unsigned int position, bool temporary, unsigned int maxUsers);
133 		void requestBanList();
134 		void requestUserList();
135 		void requestACL(unsigned int channel);
136 		void registerUser(unsigned int uiSession);
137 		void kickBanUser(unsigned int uiSession, const QString &reason, bool ban);
138 		void sendUserTextMessage(unsigned int uiSession, const QString &message_);
139 		void sendChannelTextMessage(unsigned int channel, const QString &message_, bool tree);
140 		void setUserComment(unsigned int uiSession, const QString &comment);
141 		void setUserTexture(unsigned int uiSession, const QByteArray &qba);
142 		void setTokens(const QStringList &tokens);
143 		void removeChannel(unsigned int channel);
144 		void addChannelLink(unsigned int channel, unsigned int link);
145 		void removeChannelLink(unsigned int channel, unsigned int link);
146 		void requestChannelPermissions(unsigned int channel);
147 		void setSelfMuteDeafState(bool mute, bool deaf);
148 		void announceRecordingState(bool recording);
149 
150 		/// Return connection information as a URL
151 		QUrl getServerURL(bool withPassword = false) const;
152 
153 		void disconnect();
154 		void run() Q_DECL_OVERRIDE;
155 	signals:
156 		void error(QAbstractSocket::SocketError, QString reason);
157 		void disconnected(QAbstractSocket::SocketError, QString reason);
158 		void connected();
159 		void pingRequested();
160 	protected slots:
161 		void message(unsigned int, const QByteArray &);
162 		void serverConnectionConnected();
163 		void serverConnectionTimeoutOnConnect();
164 		void serverConnectionStateChanged(QAbstractSocket::SocketState);
165 		void serverConnectionClosed(QAbstractSocket::SocketError, const QString &);
166 		void setSslErrors(const QList<QSslError> &);
167 		void udpReady();
168 		void hostnameResolved();
169 	private slots:
170 		void sendPingInternal();
171 	public slots:
172 		void sendPing();
173 };
174 
175 typedef boost::shared_ptr<ServerHandler> ServerHandlerPtr;
176 
177 #endif
178