Welcome to mirror list, hosted at ThFree Co, Russian Federation.

ServerUser.h « murmur « src - github.com/mumble-voip/mumble.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: 21283324fefb405b9106a8bc915fa298762de241 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
// Copyright 2005-2020 The Mumble Developers. All rights reserved.
// Use of this source code is governed by a BSD-style license
// that can be found in the LICENSE file at the root of the
// Mumble source tree or at <https://www.mumble.info/LICENSE>.

#ifndef MUMBLE_MURMUR_SERVERUSER_H_
#define MUMBLE_MURMUR_SERVERUSER_H_

#include <QtCore/QtGlobal>

#ifdef Q_OS_WIN
# include "win.h"
#endif

#include "Connection.h"
#include "Timer.h"
#include "User.h"
#include "HostAddress.h"

#include <QtCore/QStringList>
#include <QtCore/QElapsedTimer>

#ifdef Q_OS_WIN
# include <winsock2.h>
#else
# include <sys/socket.h>
#endif

// Unfortunately, this needs to be "large enough" to hold
// enough frames to account for both short-term and
// long-term "maladjustments".

#define N_BANDWIDTH_SLOTS 360

struct BandwidthRecord {
	int iRecNum;
	int iSum;
	Timer tFirst;
	Timer tIdleControl;
	unsigned short a_iBW[N_BANDWIDTH_SLOTS];
	Timer a_qtWhen[N_BANDWIDTH_SLOTS];
	mutable QMutex qmMutex;

	BandwidthRecord();
	bool addFrame(int size, int maxpersec);
	int onlineSeconds() const;
	int idleSeconds() const;
	void resetIdleSeconds();
	int bandwidth() const;
};

struct WhisperTarget {
	struct Channel {
		int iId;
		bool bChildren;
		bool bLinks;
		QString qsGroup;
	};
	QList<unsigned int> qlSessions;
	QList<WhisperTarget::Channel> qlChannels;
};

class Server;

/// A simple implementation for rate-limiting.
/// See https://en.wikipedia.org/wiki/Leaky_bucket
class LeakyBucket {
	private:
		/// The amount of tokens that are drained per second.
		/// (The sze of the whole in the bucket)
		unsigned int m_tokensPerSec;
		/// The maximum amount of tokens that may be encountered.
		/// (The capacity of the bucket)
		unsigned int m_maxTokens;
		/// The amount of tokens currently stored
		/// (The amount of whater currently in the bucket)
		long m_currentTokens;
		/// A timer that is used to measure time intervals. It is essential
		/// that this timer uses a monotonic clock (which is why QElapsedTimer is
		/// used instead of QTime or QDateTime).
		QElapsedTimer m_timer;

	public:
		/// @param tokens The amount of tokens that should be added.
		/// @returns Whether adding this amount of tokens triggers rate
		/// 	limiting (true means the corresponding packet has to be
		/// 	discared and false means the packet may be processed)
		bool ratelimit(int tokens);

		LeakyBucket(unsigned int tokensPerSec, unsigned int maxTokens);
};

class ServerUser : public Connection, public User {
	private:
		Q_OBJECT
		Q_DISABLE_COPY(ServerUser)
	protected:
		Server *s;
	public:
		enum State { Connected, Authenticated };
		State sState;
		operator QString() const;

		float dUDPPingAvg, dUDPPingVar;
		float dTCPPingAvg, dTCPPingVar;
		quint32 uiUDPPackets, uiTCPPackets;

		unsigned int uiVersion;
		QString qsRelease;
		QString qsOS;
		QString qsOSVersion;

		std::string ssContext;
		QString qsIdentity;

		bool bVerified;
		QStringList qslEmail;

		HostAddress haAddress;

		/// Holds whether the user is using TCP
		/// or UDP for voice packets.
		///
		/// If the flag is 0, the user is using
		/// TCP.
		///
		/// If the flag is 1, the user is using
		/// UDP.
		QAtomicInt aiUdpFlag;

		QList<int> qlCodecs;
		bool bOpus;

		QStringList qslAccessTokens;

		QMap<int, WhisperTarget> qmTargets;
		typedef QPair<QSet<ServerUser *>, QSet<ServerUser *> > TargetCache;
		QMap<int, TargetCache> qmTargetCache;
		QMap<QString, QString> qmWhisperRedirect;

		LeakyBucket leakyBucket;

		int iLastPermissionCheck;
		QMap<int, unsigned int> qmPermissionSent;
#ifdef Q_OS_UNIX
		int sUdpSocket;
#else
		SOCKET sUdpSocket;
#endif
		BandwidthRecord bwr;
		struct sockaddr_storage saiUdpAddress;
		struct sockaddr_storage saiTcpLocalAddress;
		ServerUser(Server *parent, QSslSocket *socket);
};

#endif