"Fossies" - the Fresh Open Source Software Archive 
Member "tdesktop-2.6.1/Telegram/SourceFiles/mtproto/details/mtproto_dcenter.cpp" (24 Feb 2021, 4726 Bytes) of package /linux/misc/tdesktop-2.6.1.tar.gz:
As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style:
standard) with prefixed line numbers and
code folding option.
Alternatively you can here
view or
download the uninterpreted source code file.
For more information about "mtproto_dcenter.cpp" see the
Fossies "Dox" file reference documentation.
1 /*
2 This file is part of Telegram Desktop,
3 the official desktop application for the Telegram messaging service.
4
5 For license and copyright information please follow this link:
6 https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
7 */
8 #include "mtproto/details/mtproto_dcenter.h"
9
10 #include "mtproto/facade.h"
11 #include "mtproto/mtproto_auth_key.h"
12 #include "mtproto/mtproto_dc_options.h"
13 #include "mtproto/mtp_instance.h"
14 #include "mtproto/special_config_request.h"
15
16 namespace MTP {
17 namespace details {
18 namespace {
19
20 constexpr auto kEnumerateDcTimeout = 8000; // 8 seconds timeout for help_getConfig to work (then move to other dc)
21 constexpr auto kSpecialRequestTimeoutMs = 6000; // 4 seconds timeout for it to work in a specially requested dc.
22
23 int IndexByType(TemporaryKeyType type) {
24 switch (type) {
25 case TemporaryKeyType::Regular: return 0;
26 case TemporaryKeyType::MediaCluster: return 1;
27 }
28 Unexpected("Type value in IndexByType.");
29 }
30
31 int IndexByType(CreatingKeyType type) {
32 switch (type) {
33 case CreatingKeyType::Persistent:
34 case CreatingKeyType::TemporaryRegular: return 0;
35 case CreatingKeyType::TemporaryMediaCluster: return 1;
36 }
37 Unexpected("Creating type value in IndexByType.");
38 }
39
40 const char *NameOfType(CreatingKeyType type) {
41 switch (type) {
42 case CreatingKeyType::Persistent: return "persistent";
43 case CreatingKeyType::TemporaryRegular: return "regular";
44 case CreatingKeyType::TemporaryMediaCluster: return "media";
45 }
46 Unexpected("Type value in NameOfType.");
47 }
48
49 } // namespace
50
51
52 TemporaryKeyType TemporaryKeyTypeByDcType(DcType type) {
53 return (type == DcType::MediaCluster)
54 ? TemporaryKeyType::MediaCluster
55 : TemporaryKeyType::Regular;
56 }
57
58 Dcenter::Dcenter(DcId dcId, AuthKeyPtr &&key)
59 : _id(dcId)
60 , _persistentKey(std::move(key)) {
61 }
62
63 DcId Dcenter::id() const {
64 return _id;
65 }
66
67 AuthKeyPtr Dcenter::getTemporaryKey(TemporaryKeyType type) const {
68 QReadLocker lock(&_mutex);
69 return _temporaryKeys[IndexByType(type)];
70 }
71
72 AuthKeyPtr Dcenter::getPersistentKey() const {
73 QReadLocker lock(&_mutex);
74 return _persistentKey;
75 }
76
77 bool Dcenter::destroyTemporaryKey(uint64 keyId) {
78 QWriteLocker lock(&_mutex);
79 for (auto &key : _temporaryKeys) {
80 if (key && key->keyId() == keyId) {
81 key = nullptr;
82 _connectionInited = false;
83 return true;
84 }
85 }
86 return false;
87 }
88
89 bool Dcenter::destroyConfirmedForgottenKey(uint64 keyId) {
90 QWriteLocker lock(&_mutex);
91 if (!_persistentKey || _persistentKey->keyId() != keyId) {
92 return false;
93 }
94 for (auto &key : _temporaryKeys) {
95 key = nullptr;
96 }
97 _persistentKey = nullptr;
98 _connectionInited = false;
99 return true;
100 }
101
102 bool Dcenter::connectionInited() const {
103 QReadLocker lock(&_mutex);
104 return _connectionInited;
105 }
106
107 void Dcenter::setConnectionInited(bool connectionInited) {
108 QWriteLocker lock(&_mutex);
109 _connectionInited = connectionInited;
110 }
111
112 CreatingKeyType Dcenter::acquireKeyCreation(DcType type) {
113 QReadLocker lock(&_mutex);
114 const auto keyType = TemporaryKeyTypeByDcType(type);
115 const auto index = IndexByType(keyType);
116 auto &key = _temporaryKeys[index];
117 if (key != nullptr) {
118 return CreatingKeyType::None;
119 }
120 auto expected = false;
121 const auto regular = IndexByType(TemporaryKeyType::Regular);
122 if (keyType == TemporaryKeyType::MediaCluster && _temporaryKeys[regular]) {
123 return !_creatingKeys[index].compare_exchange_strong(expected, true)
124 ? CreatingKeyType::None
125 : CreatingKeyType::TemporaryMediaCluster;
126 }
127 return !_creatingKeys[regular].compare_exchange_strong(expected, true)
128 ? CreatingKeyType::None
129 : (type != DcType::Cdn && !_persistentKey)
130 ? CreatingKeyType::Persistent
131 : CreatingKeyType::TemporaryRegular;
132 }
133
134 bool Dcenter::releaseKeyCreationOnDone(
135 CreatingKeyType type,
136 const AuthKeyPtr &temporaryKey,
137 const AuthKeyPtr &persistentKeyUsedForBind) {
138 Expects(_creatingKeys[IndexByType(type)]);
139 Expects(_temporaryKeys[IndexByType(type)] == nullptr);
140 Expects(temporaryKey != nullptr);
141
142 QWriteLocker lock(&_mutex);
143 if (type == CreatingKeyType::Persistent) {
144 _persistentKey = persistentKeyUsedForBind;
145 } else if (_persistentKey != persistentKeyUsedForBind) {
146 return false;
147 }
148 _temporaryKeys[IndexByType(type)] = temporaryKey;
149 _creatingKeys[IndexByType(type)] = false;
150 _connectionInited = false;
151
152 DEBUG_LOG(("AuthKey Info: Dcenter::releaseKeyCreationOnDone(%1, %2, %3)."
153 ).arg(NameOfType(type)
154 ).arg(temporaryKey ? temporaryKey->keyId() : 0
155 ).arg(persistentKeyUsedForBind
156 ? persistentKeyUsedForBind->keyId()
157 : 0));
158 return true;
159 }
160
161 void Dcenter::releaseKeyCreationOnFail(CreatingKeyType type) {
162 Expects(_creatingKeys[IndexByType(type)]);
163 Expects(_temporaryKeys[IndexByType(type)] == nullptr);
164
165 _creatingKeys[IndexByType(type)] = false;
166 }
167
168 } // namespace details
169 } // namespace MTP