mtp_instance.cpp 58 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117
  1. /*
  2. This file is part of Telegram Desktop,
  3. the official desktop application for the Telegram messaging service.
  4. For license and copyright information please follow this link:
  5. https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
  6. */
  7. #include "mtproto/mtp_instance.h"
  8. #include "mtproto/details/mtproto_dcenter.h"
  9. #include "mtproto/details/mtproto_rsa_public_key.h"
  10. #include "mtproto/special_config_request.h"
  11. #include "mtproto/session.h"
  12. #include "mtproto/mtproto_config.h"
  13. #include "mtproto/mtproto_dc_options.h"
  14. #include "mtproto/config_loader.h"
  15. #include "mtproto/sender.h"
  16. #include "storage/localstorage.h"
  17. #include "calls/calls_instance.h"
  18. #include "main/main_account.h" // Account::configUpdated.
  19. #include "core/application.h"
  20. #include "core/core_settings.h"
  21. #include "lang/lang_instance.h"
  22. #include "lang/lang_cloud_manager.h"
  23. #include "base/unixtime.h"
  24. #include "base/call_delayed.h"
  25. #include "base/timer.h"
  26. #include "base/network_reachability.h"
  27. namespace MTP {
  28. namespace {
  29. constexpr auto kConfigBecomesOldIn = 2 * 60 * crl::time(1000);
  30. constexpr auto kConfigBecomesOldForBlockedIn = 8 * crl::time(1000);
  31. using namespace details;
  32. std::atomic<int> GlobalAtomicRequestId = 0;
  33. } // namespace
  34. namespace details {
  35. int GetNextRequestId() {
  36. const auto result = ++GlobalAtomicRequestId;
  37. if (result == std::numeric_limits<int>::max() / 2) {
  38. GlobalAtomicRequestId = 0;
  39. }
  40. return result;
  41. }
  42. } // namespace details
  43. class Instance::Private : private Sender {
  44. public:
  45. Private(
  46. not_null<Instance*> instance,
  47. Instance::Mode mode,
  48. Fields &&fields);
  49. void start();
  50. [[nodiscard]] Config &config() const;
  51. [[nodiscard]] const ConfigFields &configValues() const;
  52. [[nodiscard]] DcOptions &dcOptions() const;
  53. [[nodiscard]] Environment environment() const;
  54. [[nodiscard]] bool isTestMode() const;
  55. void resolveProxyDomain(const QString &host);
  56. void setGoodProxyDomain(const QString &host, const QString &ip);
  57. void suggestMainDcId(DcId mainDcId);
  58. void setMainDcId(DcId mainDcId);
  59. [[nodiscard]] bool hasMainDcId() const;
  60. [[nodiscard]] DcId mainDcId() const;
  61. [[nodiscard]] rpl::producer<DcId> mainDcIdValue() const;
  62. [[nodiscard]] rpl::producer<> writeKeysRequests() const;
  63. void dcPersistentKeyChanged(DcId dcId, const AuthKeyPtr &persistentKey);
  64. void dcTemporaryKeyChanged(DcId dcId);
  65. [[nodiscard]] rpl::producer<DcId> dcTemporaryKeyChanged() const;
  66. [[nodiscard]] AuthKeysList getKeysForWrite() const;
  67. void addKeysForDestroy(AuthKeysList &&keys);
  68. [[nodiscard]] rpl::producer<> allKeysDestroyed() const;
  69. // Thread safe.
  70. [[nodiscard]] QString deviceModel() const;
  71. [[nodiscard]] QString systemVersion() const;
  72. // Main thread.
  73. void requestConfig();
  74. void requestConfigIfOld();
  75. void requestCDNConfig();
  76. void setUserPhone(const QString &phone);
  77. void badConfigurationError();
  78. void syncHttpUnixtime();
  79. void restartedByTimeout(ShiftedDcId shiftedDcId);
  80. [[nodiscard]] rpl::producer<ShiftedDcId> restartsByTimeout() const;
  81. [[nodiscard]] auto nonPremiumDelayedRequests() const
  82. -> rpl::producer<mtpRequestId>;
  83. void restart();
  84. void restart(ShiftedDcId shiftedDcId);
  85. [[nodiscard]] int32 dcstate(ShiftedDcId shiftedDcId = 0);
  86. [[nodiscard]] QString dctransport(ShiftedDcId shiftedDcId = 0);
  87. void ping();
  88. void cancel(mtpRequestId requestId);
  89. [[nodiscard]] int32 state(mtpRequestId requestId); // < 0 means waiting for such count of ms
  90. void killSession(ShiftedDcId shiftedDcId);
  91. void stopSession(ShiftedDcId shiftedDcId);
  92. void reInitConnection(DcId dcId);
  93. void logout(Fn<void()> done);
  94. not_null<Dcenter*> getDcById(ShiftedDcId shiftedDcId);
  95. Dcenter *findDc(ShiftedDcId shiftedDcId);
  96. not_null<Dcenter*> addDc(
  97. ShiftedDcId shiftedDcId,
  98. AuthKeyPtr &&key = nullptr);
  99. void removeDc(ShiftedDcId shiftedDcId);
  100. void sendRequest(
  101. mtpRequestId requestId,
  102. SerializedRequest &&request,
  103. ResponseHandler &&callbacks,
  104. ShiftedDcId shiftedDcId,
  105. crl::time msCanWait,
  106. bool needsLayer,
  107. mtpRequestId afterRequestId);
  108. void registerRequest(mtpRequestId requestId, ShiftedDcId shiftedDcId);
  109. void unregisterRequest(mtpRequestId requestId);
  110. void storeRequest(
  111. mtpRequestId requestId,
  112. const SerializedRequest &request,
  113. ResponseHandler &&callbacks);
  114. SerializedRequest getRequest(mtpRequestId requestId);
  115. [[nodiscard]] bool hasCallback(mtpRequestId requestId) const;
  116. void processCallback(const Response &response);
  117. void processUpdate(const Response &message);
  118. void onStateChange(ShiftedDcId shiftedDcId, int32 state);
  119. void onSessionReset(ShiftedDcId shiftedDcId);
  120. // return true if need to clean request data
  121. bool rpcErrorOccured(
  122. const Response &response,
  123. const FailHandler &onFail,
  124. const Error &error);
  125. inline bool rpcErrorOccured(
  126. const Response &response,
  127. const ResponseHandler &handler,
  128. const Error &error) {
  129. return rpcErrorOccured(response, handler.fail, error);
  130. }
  131. void setUpdatesHandler(Fn<void(const Response&)> handler);
  132. void setGlobalFailHandler(
  133. Fn<void(const Error&, const Response&)> handler);
  134. void setStateChangedHandler(Fn<void(ShiftedDcId shiftedDcId, int32 state)> handler);
  135. void setSessionResetHandler(Fn<void(ShiftedDcId shiftedDcId)> handler);
  136. void clearGlobalHandlers();
  137. [[nodiscard]] not_null<Session*> getSession(ShiftedDcId shiftedDcId);
  138. bool isNormal() const {
  139. return (_mode == Instance::Mode::Normal);
  140. }
  141. bool isKeysDestroyer() const {
  142. return (_mode == Instance::Mode::KeysDestroyer);
  143. }
  144. void scheduleKeyDestroy(ShiftedDcId shiftedDcId);
  145. void keyWasPossiblyDestroyed(ShiftedDcId shiftedDcId);
  146. void performKeyDestroy(ShiftedDcId shiftedDcId);
  147. void completedKeyDestroy(ShiftedDcId shiftedDcId);
  148. void keyDestroyedOnServer(ShiftedDcId shiftedDcId, uint64 keyId);
  149. void prepareToDestroy();
  150. [[nodiscard]] rpl::lifetime &lifetime();
  151. private:
  152. void importDone(
  153. const MTPauth_Authorization &result,
  154. const Response &response);
  155. bool importFail(const Error &error, const Response &response);
  156. void exportDone(
  157. const MTPauth_ExportedAuthorization &result,
  158. const Response &response);
  159. bool exportFail(const Error &error, const Response &response);
  160. bool onErrorDefault(const Error &error, const Response &response);
  161. void unpaused();
  162. Session *findSession(ShiftedDcId shiftedDcId);
  163. not_null<Session*> startSession(ShiftedDcId shiftedDcId);
  164. void scheduleSessionDestroy(ShiftedDcId shiftedDcId);
  165. [[nodiscard]] not_null<QThread*> getThreadForDc(ShiftedDcId shiftedDcId);
  166. void applyDomainIps(
  167. const QString &host,
  168. const QStringList &ips,
  169. crl::time expireAt);
  170. void logoutGuestDcs();
  171. bool logoutGuestDone(mtpRequestId requestId);
  172. void requestConfigIfExpired();
  173. void configLoadDone(const MTPConfig &result);
  174. bool configLoadFail(const Error &error);
  175. std::optional<ShiftedDcId> queryRequestByDc(
  176. mtpRequestId requestId) const;
  177. std::optional<ShiftedDcId> changeRequestByDc(
  178. mtpRequestId requestId, DcId newdc);
  179. void checkDelayedRequests();
  180. const not_null<Instance*> _instance;
  181. const Instance::Mode _mode = Instance::Mode::Normal;
  182. const std::unique_ptr<Config> _config;
  183. const std::shared_ptr<base::NetworkReachability> _networkReachability;
  184. std::unique_ptr<QThread> _mainSessionThread;
  185. std::unique_ptr<QThread> _otherSessionsThread;
  186. std::vector<std::unique_ptr<QThread>> _fileSessionThreads;
  187. QString _deviceModelDefault;
  188. QString _systemVersion;
  189. mutable QMutex _deviceModelMutex;
  190. QString _customDeviceModel;
  191. rpl::variable<DcId> _mainDcId = Fields::kDefaultMainDc;
  192. bool _mainDcIdForced = false;
  193. base::flat_map<DcId, std::unique_ptr<Dcenter>> _dcenters;
  194. std::vector<std::unique_ptr<Dcenter>> _dcentersToDestroy;
  195. rpl::event_stream<DcId> _dcTemporaryKeyChanged;
  196. Session *_mainSession = nullptr;
  197. base::flat_map<ShiftedDcId, std::unique_ptr<Session>> _sessions;
  198. std::vector<std::unique_ptr<Session>> _sessionsToDestroy;
  199. rpl::event_stream<ShiftedDcId> _restartsByTimeout;
  200. std::unique_ptr<ConfigLoader> _configLoader;
  201. std::unique_ptr<DomainResolver> _domainResolver;
  202. std::unique_ptr<SpecialConfigRequest> _httpUnixtimeLoader;
  203. QString _userPhone;
  204. mtpRequestId _cdnConfigLoadRequestId = 0;
  205. crl::time _lastConfigLoadedTime = 0;
  206. crl::time _configExpiresAt = 0;
  207. base::flat_map<DcId, AuthKeyPtr> _keysForWrite;
  208. base::flat_map<ShiftedDcId, mtpRequestId> _logoutGuestRequestIds;
  209. rpl::event_stream<> _writeKeysRequests;
  210. rpl::event_stream<> _allKeysDestroyed;
  211. // holds dcWithShift for request to this dc or -dc for request to main dc
  212. std::map<mtpRequestId, ShiftedDcId> _requestsByDc;
  213. mutable QMutex _requestByDcLock;
  214. // holds target dcWithShift for auth export request
  215. std::map<mtpRequestId, ShiftedDcId> _authExportRequests;
  216. std::map<mtpRequestId, ResponseHandler> _parserMap;
  217. mutable QMutex _parserMapLock;
  218. std::map<mtpRequestId, SerializedRequest> _requestMap;
  219. QReadWriteLock _requestMapLock;
  220. std::deque<std::pair<mtpRequestId, crl::time>> _delayedRequests;
  221. base::flat_map<mtpRequestId, mtpRequestId> _dependentRequests;
  222. mutable QMutex _dependentRequestsLock;
  223. std::map<mtpRequestId, int> _requestsDelays;
  224. std::set<mtpRequestId> _badGuestDcRequests;
  225. std::map<DcId, std::vector<mtpRequestId>> _authWaiters;
  226. Fn<void(const Response&)> _updatesHandler;
  227. Fn<void(const Error&, const Response&)> _globalFailHandler;
  228. Fn<void(ShiftedDcId shiftedDcId, int32 state)> _stateChangedHandler;
  229. Fn<void(ShiftedDcId shiftedDcId)> _sessionResetHandler;
  230. rpl::event_stream<mtpRequestId> _nonPremiumDelayedRequests;
  231. base::Timer _checkDelayedTimer;
  232. Core::SettingsProxy &_proxySettings;
  233. rpl::lifetime _lifetime;
  234. };
  235. Instance::Fields::Fields() = default;
  236. Instance::Fields::Fields(Fields &&other) = default;
  237. auto Instance::Fields::operator=(Fields &&other) -> Fields & = default;
  238. Instance::Fields::~Fields() = default;
  239. Instance::Private::Private(
  240. not_null<Instance*> instance,
  241. Instance::Mode mode,
  242. Fields &&fields)
  243. : Sender(instance)
  244. , _instance(instance)
  245. , _mode(mode)
  246. , _config(std::move(fields.config))
  247. , _networkReachability(base::NetworkReachability::Instance())
  248. , _proxySettings(Core::App().settings().proxy()) {
  249. Expects(_config != nullptr);
  250. const auto idealThreadPoolSize = QThread::idealThreadCount();
  251. _fileSessionThreads.resize(2 * std::max(idealThreadPoolSize / 2, 1));
  252. details::unpaused(
  253. ) | rpl::start_with_next([=] {
  254. unpaused();
  255. }, _lifetime);
  256. _networkReachability->availableChanges(
  257. ) | rpl::start_with_next([=](bool available) {
  258. restart();
  259. }, _lifetime);
  260. _deviceModelDefault = std::move(fields.deviceModel);
  261. _systemVersion = std::move(fields.systemVersion);
  262. _customDeviceModel = Core::App().settings().customDeviceModel();
  263. Core::App().settings().customDeviceModelChanges(
  264. ) | rpl::start_with_next([=](const QString &value) {
  265. QMutexLocker lock(&_deviceModelMutex);
  266. _customDeviceModel = value;
  267. lock.unlock();
  268. reInitConnection(mainDcId());
  269. }, _lifetime);
  270. for (auto &key : fields.keys) {
  271. auto dcId = key->dcId();
  272. auto shiftedDcId = dcId;
  273. if (isKeysDestroyer()) {
  274. shiftedDcId = MTP::destroyKeyNextDcId(shiftedDcId);
  275. // There could be several keys for one dc if we're destroying them.
  276. // Place them all in separate shiftedDcId so that they won't conflict.
  277. while (_keysForWrite.find(shiftedDcId) != _keysForWrite.cend()) {
  278. shiftedDcId = MTP::destroyKeyNextDcId(shiftedDcId);
  279. }
  280. }
  281. _keysForWrite[shiftedDcId] = key;
  282. addDc(shiftedDcId, std::move(key));
  283. }
  284. if (fields.mainDcId != Fields::kNotSetMainDc) {
  285. _mainDcId = fields.mainDcId;
  286. _mainDcIdForced = true;
  287. }
  288. _proxySettings.connectionTypeChanges(
  289. ) | rpl::start_with_next([=] {
  290. if (_configLoader) {
  291. _configLoader->setProxyEnabled(_proxySettings.isEnabled());
  292. }
  293. }, _lifetime);
  294. }
  295. void Instance::Private::start() {
  296. if (isKeysDestroyer()) {
  297. for (const auto &[shiftedDcId, dc] : _dcenters) {
  298. startSession(shiftedDcId);
  299. }
  300. } else if (hasMainDcId()) {
  301. _mainSession = startSession(mainDcId());
  302. }
  303. _checkDelayedTimer.setCallback([this] { checkDelayedRequests(); });
  304. Assert(!hasMainDcId() == isKeysDestroyer());
  305. requestConfig();
  306. }
  307. void Instance::Private::resolveProxyDomain(const QString &host) {
  308. if (!_domainResolver) {
  309. _domainResolver = std::make_unique<DomainResolver>([=](
  310. const QString &host,
  311. const QStringList &ips,
  312. crl::time expireAt) {
  313. applyDomainIps(host, ips, expireAt);
  314. });
  315. }
  316. _domainResolver->resolve(host);
  317. }
  318. void Instance::Private::applyDomainIps(
  319. const QString &host,
  320. const QStringList &ips,
  321. crl::time expireAt) {
  322. const auto applyToProxy = [&](ProxyData &proxy) {
  323. if (!proxy.tryCustomResolve() || proxy.host != host) {
  324. return false;
  325. }
  326. proxy.resolvedExpireAt = expireAt;
  327. auto copy = ips;
  328. auto &current = proxy.resolvedIPs;
  329. const auto i = ranges::remove_if(current, [&](const QString &ip) {
  330. const auto index = copy.indexOf(ip);
  331. if (index < 0) {
  332. return true;
  333. }
  334. copy.removeAt(index);
  335. return false;
  336. });
  337. if (i == end(current) && copy.isEmpty()) {
  338. // Even if the proxy was changed already, we still want
  339. // to refreshOptions in all sessions across all instances.
  340. return true;
  341. }
  342. current.erase(i, end(current));
  343. for (const auto &ip : std::as_const(copy)) {
  344. proxy.resolvedIPs.push_back(ip);
  345. }
  346. return true;
  347. };
  348. for (auto &proxy : _proxySettings.list()) {
  349. applyToProxy(proxy);
  350. }
  351. auto selected = _proxySettings.selected();
  352. if (applyToProxy(selected) && _proxySettings.isEnabled()) {
  353. _proxySettings.setSelected(selected);
  354. for (const auto &[shiftedDcId, session] : _sessions) {
  355. session->refreshOptions();
  356. }
  357. }
  358. _instance->proxyDomainResolved(host, ips, expireAt);
  359. }
  360. void Instance::Private::setGoodProxyDomain(
  361. const QString &host,
  362. const QString &ip) {
  363. const auto applyToProxy = [&](ProxyData &proxy) {
  364. if (!proxy.tryCustomResolve() || proxy.host != host) {
  365. return false;
  366. }
  367. auto &current = proxy.resolvedIPs;
  368. auto i = ranges::find(current, ip);
  369. if (i == end(current) || i == begin(current)) {
  370. return false;
  371. }
  372. while (i != begin(current)) {
  373. const auto j = i--;
  374. std::swap(*i, *j);
  375. }
  376. return true;
  377. };
  378. for (auto &proxy : _proxySettings.list()) {
  379. applyToProxy(proxy);
  380. }
  381. auto selected = _proxySettings.selected();
  382. if (applyToProxy(selected) && _proxySettings.isEnabled()) {
  383. _proxySettings.setSelected(selected);
  384. Core::App().refreshGlobalProxy();
  385. }
  386. }
  387. void Instance::Private::suggestMainDcId(DcId mainDcId) {
  388. if (!_mainDcIdForced) {
  389. setMainDcId(mainDcId);
  390. }
  391. }
  392. void Instance::Private::setMainDcId(DcId mainDcId) {
  393. if (!_mainSession) {
  394. LOG(("MTP Error: attempting to change mainDcId in an MTP instance without main session."));
  395. return;
  396. }
  397. _mainDcIdForced = true;
  398. const auto oldMainDcId = _mainSession->getDcWithShift();
  399. if (oldMainDcId != mainDcId) {
  400. scheduleSessionDestroy(oldMainDcId);
  401. scheduleSessionDestroy(mainDcId);
  402. _mainSession = startSession(mainDcId);
  403. }
  404. _mainDcId = mainDcId;
  405. _writeKeysRequests.fire({});
  406. }
  407. bool Instance::Private::hasMainDcId() const {
  408. return (_mainDcId.current() != Fields::kNoneMainDc);
  409. }
  410. DcId Instance::Private::mainDcId() const {
  411. Expects(hasMainDcId());
  412. return _mainDcId.current();
  413. }
  414. rpl::producer<DcId> Instance::Private::mainDcIdValue() const {
  415. Expects(_mainDcId.current() != Fields::kNoneMainDc);
  416. return _mainDcId.value();
  417. }
  418. void Instance::Private::requestConfig() {
  419. if (_configLoader || isKeysDestroyer()) {
  420. return;
  421. }
  422. _configLoader = std::make_unique<ConfigLoader>(
  423. _instance,
  424. _userPhone,
  425. [=](const MTPConfig &result) { configLoadDone(result); },
  426. [=](const Error &error, const Response &) {
  427. return configLoadFail(error);
  428. },
  429. _proxySettings.isEnabled());
  430. _configLoader->load();
  431. }
  432. void Instance::Private::setUserPhone(const QString &phone) {
  433. if (_userPhone != phone) {
  434. _userPhone = phone;
  435. if (_configLoader) {
  436. _configLoader->setPhone(_userPhone);
  437. }
  438. }
  439. }
  440. void Instance::Private::badConfigurationError() {
  441. if (_mode == Mode::Normal) {
  442. Core::App().badMtprotoConfigurationError();
  443. }
  444. }
  445. void Instance::Private::syncHttpUnixtime() {
  446. if (base::unixtime::http_valid() || _httpUnixtimeLoader) {
  447. return;
  448. }
  449. _httpUnixtimeLoader = std::make_unique<SpecialConfigRequest>([=] {
  450. InvokeQueued(_instance, [=] {
  451. _httpUnixtimeLoader = nullptr;
  452. });
  453. }, isTestMode(), configValues().txtDomainString);
  454. }
  455. void Instance::Private::restartedByTimeout(ShiftedDcId shiftedDcId) {
  456. _restartsByTimeout.fire_copy(shiftedDcId);
  457. }
  458. rpl::producer<ShiftedDcId> Instance::Private::restartsByTimeout() const {
  459. return _restartsByTimeout.events();
  460. }
  461. auto Instance::Private::nonPremiumDelayedRequests() const
  462. -> rpl::producer<mtpRequestId> {
  463. return _nonPremiumDelayedRequests.events();
  464. }
  465. void Instance::Private::requestConfigIfOld() {
  466. const auto timeout = _config->values().blockedMode
  467. ? kConfigBecomesOldForBlockedIn
  468. : kConfigBecomesOldIn;
  469. if (crl::now() - _lastConfigLoadedTime >= timeout) {
  470. requestConfig();
  471. }
  472. }
  473. void Instance::Private::requestConfigIfExpired() {
  474. const auto requestIn = (_configExpiresAt - crl::now());
  475. if (requestIn > 0) {
  476. base::call_delayed(
  477. std::min(requestIn, 3600 * crl::time(1000)),
  478. _instance,
  479. [=] { requestConfigIfExpired(); });
  480. } else {
  481. requestConfig();
  482. }
  483. }
  484. void Instance::Private::requestCDNConfig() {
  485. if (_cdnConfigLoadRequestId || !hasMainDcId()) {
  486. return;
  487. }
  488. _cdnConfigLoadRequestId = request(
  489. MTPhelp_GetCdnConfig()
  490. ).done([this](const MTPCdnConfig &result) {
  491. _cdnConfigLoadRequestId = 0;
  492. result.match([&](const MTPDcdnConfig &data) {
  493. dcOptions().setCDNConfig(data);
  494. });
  495. Local::writeSettings();
  496. }).send();
  497. }
  498. void Instance::Private::restart() {
  499. for (const auto &[shiftedDcId, session] : _sessions) {
  500. session->restart();
  501. }
  502. }
  503. void Instance::Private::restart(ShiftedDcId shiftedDcId) {
  504. const auto dcId = BareDcId(shiftedDcId);
  505. for (const auto &[shiftedDcId, session] : _sessions) {
  506. if (BareDcId(shiftedDcId) == dcId) {
  507. session->restart();
  508. }
  509. }
  510. }
  511. int32 Instance::Private::dcstate(ShiftedDcId shiftedDcId) {
  512. if (!shiftedDcId) {
  513. Assert(_mainSession != nullptr);
  514. return _mainSession->getState();
  515. }
  516. if (!BareDcId(shiftedDcId)) {
  517. Assert(_mainSession != nullptr);
  518. shiftedDcId += BareDcId(_mainSession->getDcWithShift());
  519. }
  520. if (const auto session = findSession(shiftedDcId)) {
  521. return session->getState();
  522. }
  523. return DisconnectedState;
  524. }
  525. QString Instance::Private::dctransport(ShiftedDcId shiftedDcId) {
  526. if (!shiftedDcId) {
  527. Assert(_mainSession != nullptr);
  528. return _mainSession->transport();
  529. }
  530. if (!BareDcId(shiftedDcId)) {
  531. Assert(_mainSession != nullptr);
  532. shiftedDcId += BareDcId(_mainSession->getDcWithShift());
  533. }
  534. if (const auto session = findSession(shiftedDcId)) {
  535. return session->transport();
  536. }
  537. return QString();
  538. }
  539. void Instance::Private::ping() {
  540. getSession(0)->ping();
  541. }
  542. void Instance::Private::cancel(mtpRequestId requestId) {
  543. if (!requestId) return;
  544. DEBUG_LOG(("MTP Info: Cancel request %1.").arg(requestId));
  545. const auto shiftedDcId = queryRequestByDc(requestId);
  546. auto msgId = mtpMsgId(0);
  547. {
  548. QWriteLocker locker(&_requestMapLock);
  549. auto it = _requestMap.find(requestId);
  550. if (it != _requestMap.end()) {
  551. msgId = *(mtpMsgId*)(it->second->constData() + 4);
  552. _requestMap.erase(it);
  553. }
  554. }
  555. unregisterRequest(requestId);
  556. if (shiftedDcId) {
  557. const auto session = getSession(qAbs(*shiftedDcId));
  558. session->cancel(requestId, msgId);
  559. }
  560. QMutexLocker locker(&_parserMapLock);
  561. _parserMap.erase(requestId);
  562. }
  563. // result < 0 means waiting for such count of ms.
  564. int32 Instance::Private::state(mtpRequestId requestId) {
  565. if (requestId > 0) {
  566. if (const auto shiftedDcId = queryRequestByDc(requestId)) {
  567. const auto session = getSession(qAbs(*shiftedDcId));
  568. return session->requestState(requestId);
  569. }
  570. return MTP::RequestSent;
  571. }
  572. const auto session = getSession(-requestId);
  573. return session->requestState(0);
  574. }
  575. void Instance::Private::killSession(ShiftedDcId shiftedDcId) {
  576. const auto i = _sessions.find(shiftedDcId);
  577. if (i != _sessions.cend()) {
  578. Assert(i->second.get() != _mainSession);
  579. }
  580. scheduleSessionDestroy(shiftedDcId);
  581. }
  582. void Instance::Private::stopSession(ShiftedDcId shiftedDcId) {
  583. if (const auto session = findSession(shiftedDcId)) {
  584. if (session != _mainSession) { // don't stop main session
  585. session->stop();
  586. }
  587. }
  588. }
  589. void Instance::Private::reInitConnection(DcId dcId) {
  590. for (const auto &[shiftedDcId, session] : _sessions) {
  591. if (BareDcId(shiftedDcId) == dcId) {
  592. session->reInitConnection();
  593. }
  594. }
  595. }
  596. void Instance::Private::logout(Fn<void()> done) {
  597. _instance->send(MTPauth_LogOut(), [=](Response) {
  598. done();
  599. return true;
  600. }, [=](const Error&, Response) {
  601. done();
  602. return true;
  603. });
  604. logoutGuestDcs();
  605. }
  606. void Instance::Private::logoutGuestDcs() {
  607. Expects(!isKeysDestroyer());
  608. auto dcIds = std::vector<DcId>();
  609. dcIds.reserve(_keysForWrite.size());
  610. for (const auto &key : _keysForWrite) {
  611. dcIds.push_back(key.first);
  612. }
  613. for (const auto dcId : dcIds) {
  614. if (dcId == mainDcId() || dcOptions().dcType(dcId) == DcType::Cdn) {
  615. continue;
  616. }
  617. const auto shiftedDcId = MTP::logoutDcId(dcId);
  618. const auto requestId = _instance->send(MTPauth_LogOut(), [=](
  619. const Response &response) {
  620. logoutGuestDone(response.requestId);
  621. return true;
  622. }, [=](const Error &, const Response &response) {
  623. logoutGuestDone(response.requestId);
  624. return true;
  625. }, shiftedDcId);
  626. _logoutGuestRequestIds.emplace(shiftedDcId, requestId);
  627. }
  628. }
  629. bool Instance::Private::logoutGuestDone(mtpRequestId requestId) {
  630. for (auto i = _logoutGuestRequestIds.begin(), e = _logoutGuestRequestIds.end(); i != e; ++i) {
  631. if (i->second == requestId) {
  632. killSession(i->first);
  633. _logoutGuestRequestIds.erase(i);
  634. return true;
  635. }
  636. }
  637. return false;
  638. }
  639. Dcenter *Instance::Private::findDc(ShiftedDcId shiftedDcId) {
  640. const auto i = _dcenters.find(shiftedDcId);
  641. return (i != _dcenters.end()) ? i->second.get() : nullptr;
  642. }
  643. not_null<Dcenter*> Instance::Private::addDc(
  644. ShiftedDcId shiftedDcId,
  645. AuthKeyPtr &&key) {
  646. const auto dcId = BareDcId(shiftedDcId);
  647. return _dcenters.emplace(
  648. shiftedDcId,
  649. std::make_unique<Dcenter>(dcId, std::move(key))
  650. ).first->second.get();
  651. }
  652. void Instance::Private::removeDc(ShiftedDcId shiftedDcId) {
  653. const auto i = _dcenters.find(shiftedDcId);
  654. if (i != _dcenters.end()) {
  655. _dcentersToDestroy.push_back(std::move(i->second));
  656. _dcenters.erase(i);
  657. }
  658. }
  659. not_null<Dcenter*> Instance::Private::getDcById(
  660. ShiftedDcId shiftedDcId) {
  661. if (const auto result = findDc(shiftedDcId)) {
  662. return result;
  663. }
  664. const auto dcId = [&] {
  665. const auto result = BareDcId(shiftedDcId);
  666. if (isTemporaryDcId(result)) {
  667. if (const auto realDcId = getRealIdFromTemporaryDcId(result)) {
  668. return realDcId;
  669. }
  670. }
  671. return result;
  672. }();
  673. if (dcId != shiftedDcId) {
  674. if (const auto result = findDc(dcId)) {
  675. return result;
  676. }
  677. }
  678. return addDc(dcId);
  679. }
  680. void Instance::Private::dcPersistentKeyChanged(
  681. DcId dcId,
  682. const AuthKeyPtr &persistentKey) {
  683. dcTemporaryKeyChanged(dcId);
  684. if (isTemporaryDcId(dcId)) {
  685. return;
  686. }
  687. const auto i = _keysForWrite.find(dcId);
  688. if (i != _keysForWrite.end() && i->second == persistentKey) {
  689. return;
  690. } else if (i == _keysForWrite.end() && !persistentKey) {
  691. return;
  692. }
  693. if (!persistentKey) {
  694. _keysForWrite.erase(i);
  695. } else if (i != _keysForWrite.end()) {
  696. i->second = persistentKey;
  697. } else {
  698. _keysForWrite.emplace(dcId, persistentKey);
  699. }
  700. DEBUG_LOG(("AuthKey Info: writing auth keys, called by dc %1"
  701. ).arg(dcId));
  702. _writeKeysRequests.fire({});
  703. }
  704. void Instance::Private::dcTemporaryKeyChanged(DcId dcId) {
  705. _dcTemporaryKeyChanged.fire_copy(dcId);
  706. }
  707. rpl::producer<DcId> Instance::Private::dcTemporaryKeyChanged() const {
  708. return _dcTemporaryKeyChanged.events();
  709. }
  710. AuthKeysList Instance::Private::getKeysForWrite() const {
  711. auto result = AuthKeysList();
  712. result.reserve(_keysForWrite.size());
  713. for (const auto &key : _keysForWrite) {
  714. result.push_back(key.second);
  715. }
  716. return result;
  717. }
  718. void Instance::Private::addKeysForDestroy(AuthKeysList &&keys) {
  719. Expects(isKeysDestroyer());
  720. for (auto &key : keys) {
  721. const auto dcId = key->dcId();
  722. auto shiftedDcId = MTP::destroyKeyNextDcId(dcId);
  723. // There could be several keys for one dc if we're destroying them.
  724. // Place them all in separate shiftedDcId so that they won't conflict.
  725. while (_keysForWrite.find(shiftedDcId) != _keysForWrite.cend()) {
  726. shiftedDcId = MTP::destroyKeyNextDcId(shiftedDcId);
  727. }
  728. _keysForWrite[shiftedDcId] = key;
  729. addDc(shiftedDcId, std::move(key));
  730. startSession(shiftedDcId);
  731. }
  732. }
  733. rpl::producer<> Instance::Private::allKeysDestroyed() const {
  734. return _allKeysDestroyed.events();
  735. }
  736. rpl::producer<> Instance::Private::writeKeysRequests() const {
  737. return _writeKeysRequests.events();
  738. }
  739. Config &Instance::Private::config() const {
  740. return *_config;
  741. }
  742. const ConfigFields &Instance::Private::configValues() const {
  743. return _config->values();
  744. }
  745. DcOptions &Instance::Private::dcOptions() const {
  746. return _config->dcOptions();
  747. }
  748. Environment Instance::Private::environment() const {
  749. return _config->environment();
  750. }
  751. bool Instance::Private::isTestMode() const {
  752. return _config->isTestMode();
  753. }
  754. QString Instance::Private::deviceModel() const {
  755. QMutexLocker lock(&_deviceModelMutex);
  756. return _customDeviceModel.isEmpty()
  757. ? _deviceModelDefault
  758. : _customDeviceModel;
  759. }
  760. QString Instance::Private::systemVersion() const {
  761. return _systemVersion;
  762. }
  763. void Instance::Private::unpaused() {
  764. for (const auto &[shiftedDcId, session] : _sessions) {
  765. session->unpaused();
  766. }
  767. }
  768. void Instance::Private::configLoadDone(const MTPConfig &result) {
  769. Expects(result.type() == mtpc_config);
  770. _configLoader.reset();
  771. _lastConfigLoadedTime = crl::now();
  772. const auto &data = result.c_config();
  773. _config->apply(data);
  774. const auto lang = qs(data.vsuggested_lang_code().value_or_empty());
  775. Lang::CurrentCloudManager().setSuggestedLanguage(lang);
  776. Lang::CurrentCloudManager().setCurrentVersions(
  777. data.vlang_pack_version().value_or_empty(),
  778. data.vbase_lang_pack_version().value_or_empty());
  779. if (const auto prefix = data.vautoupdate_url_prefix()) {
  780. Local::writeAutoupdatePrefix(qs(*prefix));
  781. }
  782. _configExpiresAt = crl::now()
  783. + (data.vexpires().v - base::unixtime::now()) * crl::time(1000);
  784. requestConfigIfExpired();
  785. }
  786. bool Instance::Private::configLoadFail(const Error &error) {
  787. if (IsDefaultHandledError(error)) return false;
  788. // loadingConfig = false;
  789. LOG(("MTP Error: failed to get config!"));
  790. return false;
  791. }
  792. std::optional<ShiftedDcId> Instance::Private::queryRequestByDc(
  793. mtpRequestId requestId) const {
  794. QMutexLocker locker(&_requestByDcLock);
  795. auto it = _requestsByDc.find(requestId);
  796. if (it != _requestsByDc.cend()) {
  797. return it->second;
  798. }
  799. return std::nullopt;
  800. }
  801. std::optional<ShiftedDcId> Instance::Private::changeRequestByDc(
  802. mtpRequestId requestId,
  803. DcId newdc) {
  804. QMutexLocker locker(&_requestByDcLock);
  805. auto it = _requestsByDc.find(requestId);
  806. if (it != _requestsByDc.cend()) {
  807. if (it->second < 0) {
  808. it->second = -newdc;
  809. } else {
  810. it->second = ShiftDcId(newdc, GetDcIdShift(it->second));
  811. }
  812. return it->second;
  813. }
  814. return std::nullopt;
  815. }
  816. void Instance::Private::checkDelayedRequests() {
  817. auto now = crl::now();
  818. while (!_delayedRequests.empty() && now >= _delayedRequests.front().second) {
  819. auto requestId = _delayedRequests.front().first;
  820. _delayedRequests.pop_front();
  821. auto dcWithShift = ShiftedDcId(0);
  822. if (const auto shiftedDcId = queryRequestByDc(requestId)) {
  823. dcWithShift = *shiftedDcId;
  824. } else {
  825. LOG(("MTP Error: could not find request dc for delayed resend, requestId %1").arg(requestId));
  826. continue;
  827. }
  828. auto request = SerializedRequest();
  829. {
  830. QReadLocker locker(&_requestMapLock);
  831. auto it = _requestMap.find(requestId);
  832. if (it == _requestMap.cend()) {
  833. DEBUG_LOG(("MTP Error: could not find request %1").arg(requestId));
  834. continue;
  835. }
  836. request = it->second;
  837. }
  838. const auto session = getSession(qAbs(dcWithShift));
  839. session->sendPrepared(request);
  840. }
  841. if (!_delayedRequests.empty()) {
  842. _checkDelayedTimer.callOnce(_delayedRequests.front().second - now);
  843. }
  844. }
  845. void Instance::Private::sendRequest(
  846. mtpRequestId requestId,
  847. SerializedRequest &&request,
  848. ResponseHandler &&callbacks,
  849. ShiftedDcId shiftedDcId,
  850. crl::time msCanWait,
  851. bool needsLayer,
  852. mtpRequestId afterRequestId) {
  853. const auto session = getSession(shiftedDcId);
  854. request->requestId = requestId;
  855. storeRequest(requestId, request, std::move(callbacks));
  856. const auto toMainDc = (shiftedDcId == 0);
  857. const auto realShiftedDcId = session->getDcWithShift();
  858. const auto signedDcId = toMainDc ? -realShiftedDcId : realShiftedDcId;
  859. registerRequest(requestId, signedDcId);
  860. request->lastSentTime = crl::now();
  861. request->needsLayer = needsLayer;
  862. if (afterRequestId) {
  863. request->after = getRequest(afterRequestId);
  864. if (request->after) {
  865. // Check if this after request is waiting in _dependentRequests.
  866. // This happens if it was after some other request and failed
  867. // to wait for it, but that other request is still processed.
  868. QMutexLocker locker(&_dependentRequestsLock);
  869. const auto i = _dependentRequests.find(afterRequestId);
  870. if (i != end(_dependentRequests)) {
  871. _dependentRequests.emplace(requestId, afterRequestId);
  872. return;
  873. }
  874. }
  875. }
  876. session->sendPrepared(request, msCanWait);
  877. }
  878. void Instance::Private::registerRequest(
  879. mtpRequestId requestId,
  880. ShiftedDcId shiftedDcId) {
  881. QMutexLocker locker(&_requestByDcLock);
  882. _requestsByDc[requestId] = shiftedDcId;
  883. }
  884. void Instance::Private::unregisterRequest(mtpRequestId requestId) {
  885. DEBUG_LOG(("MTP Info: unregistering request %1.").arg(requestId));
  886. _requestsDelays.erase(requestId);
  887. {
  888. QWriteLocker locker(&_requestMapLock);
  889. _requestMap.erase(requestId);
  890. }
  891. {
  892. QMutexLocker locker(&_requestByDcLock);
  893. _requestsByDc.erase(requestId);
  894. }
  895. {
  896. auto toRemove = base::flat_set<mtpRequestId>();
  897. auto toResend = base::flat_set<mtpRequestId>();
  898. toRemove.emplace(requestId);
  899. QMutexLocker locker(&_dependentRequestsLock);
  900. auto handling = 0;
  901. do {
  902. handling = toResend.size();
  903. for (const auto &[resendingId, afterId] : _dependentRequests) {
  904. if (toRemove.contains(afterId)) {
  905. toRemove.emplace(resendingId);
  906. toResend.emplace(resendingId);
  907. }
  908. }
  909. } while (handling != toResend.size());
  910. for (const auto removingId : toRemove) {
  911. _dependentRequests.remove(removingId);
  912. }
  913. locker.unlock();
  914. for (const auto resendingId : toResend) {
  915. if (const auto shiftedDcId = queryRequestByDc(resendingId)) {
  916. SerializedRequest request;
  917. {
  918. QReadLocker locker(&_requestMapLock);
  919. auto it = _requestMap.find(resendingId);
  920. if (it == _requestMap.cend()) {
  921. LOG(("MTP Error: could not find dependent request %1").arg(resendingId));
  922. return;
  923. }
  924. request = it->second;
  925. }
  926. getSession(qAbs(*shiftedDcId))->sendPrepared(request);
  927. }
  928. }
  929. }
  930. }
  931. void Instance::Private::storeRequest(
  932. mtpRequestId requestId,
  933. const SerializedRequest &request,
  934. ResponseHandler &&callbacks) {
  935. if (callbacks.done || callbacks.fail) {
  936. QMutexLocker locker(&_parserMapLock);
  937. _parserMap.emplace(requestId, std::move(callbacks));
  938. }
  939. {
  940. QWriteLocker locker(&_requestMapLock);
  941. _requestMap.emplace(requestId, request);
  942. }
  943. }
  944. SerializedRequest Instance::Private::getRequest(mtpRequestId requestId) {
  945. auto result = SerializedRequest();
  946. {
  947. QReadLocker locker(&_requestMapLock);
  948. auto it = _requestMap.find(requestId);
  949. if (it != _requestMap.cend()) {
  950. result = it->second;
  951. }
  952. }
  953. return result;
  954. }
  955. bool Instance::Private::hasCallback(mtpRequestId requestId) const {
  956. QMutexLocker locker(&_parserMapLock);
  957. auto it = _parserMap.find(requestId);
  958. return (it != _parserMap.cend());
  959. }
  960. void Instance::Private::processCallback(const Response &response) {
  961. const auto requestId = response.requestId;
  962. ResponseHandler handler;
  963. {
  964. QMutexLocker locker(&_parserMapLock);
  965. auto it = _parserMap.find(requestId);
  966. if (it != _parserMap.cend()) {
  967. handler = std::move(it->second);
  968. _parserMap.erase(it);
  969. DEBUG_LOG(("RPC Info: found parser for request %1, trying to parse response...").arg(requestId));
  970. }
  971. }
  972. if (handler.done || handler.fail) {
  973. const auto handleError = [&](const Error &error) {
  974. DEBUG_LOG(("RPC Info: "
  975. "error received, code %1, type %2, description: %3").arg(
  976. QString::number(error.code()),
  977. error.type(),
  978. error.description()));
  979. const auto guard = QPointer<Instance>(_instance);
  980. if (rpcErrorOccured(response, handler, error) && guard) {
  981. unregisterRequest(requestId);
  982. } else if (guard) {
  983. QMutexLocker locker(&_parserMapLock);
  984. _parserMap.emplace(requestId, std::move(handler));
  985. }
  986. };
  987. auto from = response.reply.constData();
  988. if (response.reply.isEmpty()) {
  989. handleError(Error::Local(
  990. "RESPONSE_PARSE_FAILED",
  991. "Empty response."));
  992. } else if (*from == mtpc_rpc_error) {
  993. auto error = MTPRpcError();
  994. handleError(
  995. Error(error.read(from, from + response.reply.size())
  996. ? error
  997. : Error::MTPLocal(
  998. "RESPONSE_PARSE_FAILED",
  999. "Error parse failed.")));
  1000. } else {
  1001. const auto guard = QPointer<Instance>(_instance);
  1002. if (handler.done && !handler.done(response) && guard) {
  1003. handleError(Error::Local(
  1004. "RESPONSE_PARSE_FAILED",
  1005. "Response parse failed."));
  1006. }
  1007. if (guard) {
  1008. unregisterRequest(requestId);
  1009. }
  1010. }
  1011. } else {
  1012. DEBUG_LOG(("RPC Info: parser not found for %1").arg(requestId));
  1013. unregisterRequest(requestId);
  1014. }
  1015. }
  1016. void Instance::Private::processUpdate(const Response &message) {
  1017. if (_updatesHandler) {
  1018. _updatesHandler(message);
  1019. }
  1020. }
  1021. void Instance::Private::onStateChange(ShiftedDcId dcWithShift, int32 state) {
  1022. if (_stateChangedHandler) {
  1023. _stateChangedHandler(dcWithShift, state);
  1024. }
  1025. }
  1026. void Instance::Private::onSessionReset(ShiftedDcId dcWithShift) {
  1027. if (_sessionResetHandler) {
  1028. _sessionResetHandler(dcWithShift);
  1029. }
  1030. }
  1031. bool Instance::Private::rpcErrorOccured(
  1032. const Response &response,
  1033. const FailHandler &onFail,
  1034. const Error &error) { // return true if need to clean request data
  1035. if (IsDefaultHandledError(error)) {
  1036. const auto guard = QPointer<Instance>(_instance);
  1037. if (onFail && onFail(error, response)) {
  1038. return true;
  1039. } else if (!guard) {
  1040. return false;
  1041. }
  1042. }
  1043. if (onErrorDefault(error, response)) {
  1044. return false;
  1045. }
  1046. LOG(("RPC Error: request %1 got fail with code %2, error %3%4").arg(
  1047. QString::number(response.requestId),
  1048. QString::number(error.code()),
  1049. error.type(),
  1050. error.description().isEmpty()
  1051. ? QString()
  1052. : QString(": %1").arg(error.description())));
  1053. if (onFail) {
  1054. const auto guard = QPointer<Instance>(_instance);
  1055. onFail(error, response);
  1056. if (!guard) {
  1057. return false;
  1058. }
  1059. }
  1060. return true;
  1061. }
  1062. void Instance::Private::importDone(
  1063. const MTPauth_Authorization &result,
  1064. const Response &response) {
  1065. const auto shiftedDcId = queryRequestByDc(response.requestId);
  1066. if (!shiftedDcId) {
  1067. LOG(("MTP Error: "
  1068. "auth import request not found in requestsByDC, requestId: %1"
  1069. ).arg(response.requestId));
  1070. //
  1071. // Don't log out on export/import problems, perhaps this is a server side error.
  1072. //
  1073. //const auto error = Error::Local(
  1074. // "AUTH_IMPORT_FAIL",
  1075. // QString("did not find import request in requestsByDC, "
  1076. // "request %1").arg(requestId));
  1077. //if (_globalFailHandler && hasAuthorization()) {
  1078. // _globalFailHandler(error, response); // auth failed in main dc
  1079. //}
  1080. return;
  1081. }
  1082. auto newdc = BareDcId(*shiftedDcId);
  1083. DEBUG_LOG(("MTP Info: auth import to dc %1 succeeded").arg(newdc));
  1084. auto &waiters = _authWaiters[newdc];
  1085. if (waiters.size()) {
  1086. QReadLocker locker(&_requestMapLock);
  1087. for (auto waitedRequestId : waiters) {
  1088. auto it = _requestMap.find(waitedRequestId);
  1089. if (it == _requestMap.cend()) {
  1090. LOG(("MTP Error: could not find request %1 for resending").arg(waitedRequestId));
  1091. continue;
  1092. }
  1093. const auto shiftedDcId = changeRequestByDc(waitedRequestId, newdc);
  1094. if (!shiftedDcId) {
  1095. LOG(("MTP Error: could not find request %1 by dc for resending").arg(waitedRequestId));
  1096. continue;
  1097. } else if (*shiftedDcId < 0) {
  1098. _instance->setMainDcId(newdc);
  1099. }
  1100. DEBUG_LOG(("MTP Info: resending request %1 to dc %2 after import auth").arg(waitedRequestId).arg(*shiftedDcId));
  1101. const auto session = getSession(*shiftedDcId);
  1102. session->sendPrepared(it->second);
  1103. }
  1104. waiters.clear();
  1105. }
  1106. }
  1107. bool Instance::Private::importFail(
  1108. const Error &error,
  1109. const Response &response) {
  1110. if (IsDefaultHandledError(error)) {
  1111. return false;
  1112. }
  1113. //
  1114. // Don't log out on export/import problems, perhaps this is a server side error.
  1115. //
  1116. //if (_globalFailHandler && hasAuthorization()) {
  1117. // _globalFailHandler(error, response); // auth import failed
  1118. //}
  1119. return true;
  1120. }
  1121. void Instance::Private::exportDone(
  1122. const MTPauth_ExportedAuthorization &result,
  1123. const Response &response) {
  1124. auto it = _authExportRequests.find(response.requestId);
  1125. if (it == _authExportRequests.cend()) {
  1126. LOG(("MTP Error: "
  1127. "auth export request target dcWithShift not found, requestId: %1"
  1128. ).arg(response.requestId));
  1129. //
  1130. // Don't log out on export/import problems, perhaps this is a server side error.
  1131. //
  1132. //const auto error = Error::Local(
  1133. // "AUTH_IMPORT_FAIL",
  1134. // QString("did not find target dcWithShift, request %1"
  1135. // ).arg(requestId));
  1136. //if (_globalFailHandler && hasAuthorization()) {
  1137. // _globalFailHandler(error, response); // auth failed in main dc
  1138. //}
  1139. return;
  1140. }
  1141. auto &data = result.c_auth_exportedAuthorization();
  1142. _instance->send(MTPauth_ImportAuthorization(
  1143. data.vid(),
  1144. data.vbytes()
  1145. ), [this](const Response &response) {
  1146. auto result = MTPauth_Authorization();
  1147. auto from = response.reply.constData();
  1148. if (!result.read(from, from + response.reply.size())) {
  1149. return false;
  1150. }
  1151. importDone(result, response);
  1152. return true;
  1153. }, [this](const Error &error, const Response &response) {
  1154. return importFail(error, response);
  1155. }, it->second);
  1156. _authExportRequests.erase(response.requestId);
  1157. }
  1158. bool Instance::Private::exportFail(
  1159. const Error &error,
  1160. const Response &response) {
  1161. if (IsDefaultHandledError(error)) {
  1162. return false;
  1163. }
  1164. auto it = _authExportRequests.find(response.requestId);
  1165. if (it != _authExportRequests.cend()) {
  1166. _authWaiters[BareDcId(it->second)].clear();
  1167. }
  1168. //
  1169. // Don't log out on export/import problems, perhaps this is a server side error.
  1170. //
  1171. //if (_globalFailHandler && hasAuthorization()) {
  1172. // _globalFailHandler(error, response); // auth failed in main dc
  1173. //}
  1174. return true;
  1175. }
  1176. bool Instance::Private::onErrorDefault(
  1177. const Error &error,
  1178. const Response &response) {
  1179. const auto requestId = response.requestId;
  1180. const auto &type = error.type();
  1181. const auto code = error.code();
  1182. auto badGuestDc = (code == 400) && (type == u"FILE_ID_INVALID"_q);
  1183. static const auto MigrateRegExp = QRegularExpression("^(FILE|PHONE|NETWORK|USER)_MIGRATE_(\\d+)$");
  1184. static const auto FloodWaitRegExp = QRegularExpression("^FLOOD_WAIT_(\\d+)$");
  1185. static const auto FloodPremiumWaitRegExp = QRegularExpression("^FLOOD_PREMIUM_WAIT_(\\d+)$");
  1186. static const auto SlowmodeWaitRegExp = QRegularExpression("^SLOWMODE_WAIT_(\\d+)$");
  1187. QRegularExpressionMatch m1, m2, m3;
  1188. if ((m1 = MigrateRegExp.match(type)).hasMatch()) {
  1189. if (!requestId) return false;
  1190. auto dcWithShift = ShiftedDcId(0);
  1191. auto newdcWithShift = ShiftedDcId(m1.captured(2).toInt());
  1192. if (const auto shiftedDcId = queryRequestByDc(requestId)) {
  1193. dcWithShift = *shiftedDcId;
  1194. } else {
  1195. LOG(("MTP Error: could not find request %1 for migrating to %2").arg(requestId).arg(newdcWithShift));
  1196. }
  1197. if (!dcWithShift || !newdcWithShift) return false;
  1198. DEBUG_LOG(("MTP Info: changing request %1 from dcWithShift%2 to dc%3").arg(requestId).arg(dcWithShift).arg(newdcWithShift));
  1199. if (dcWithShift < 0) { // newdc shift = 0
  1200. if (false/* && hasAuthorization() && _authExportRequests.find(requestId) == _authExportRequests.cend()*/) {
  1201. //
  1202. // migrate not supported at this moment
  1203. // this was not tested even once
  1204. //
  1205. //DEBUG_LOG(("MTP Info: importing auth to dc %1").arg(newdcWithShift));
  1206. //auto &waiters(_authWaiters[newdcWithShift]);
  1207. //if (waiters.empty()) {
  1208. // auto exportRequestId = _instance->send(MTPauth_ExportAuthorization(
  1209. // MTP_int(newdcWithShift)
  1210. // ), [this](const Response &response) {
  1211. // auto result = MTPauth_ExportedAuthorization();
  1212. // auto from = response.reply.constData();
  1213. // if (!result.read(from, from + response.reply.size())) {
  1214. // return false;
  1215. // }
  1216. // exportDone(result, response);
  1217. // return true;
  1218. // }, [this](const Error &error, const Response &response) {
  1219. // return exportFail(error, response);
  1220. // });
  1221. // _authExportRequests.emplace(exportRequestId, newdcWithShift);
  1222. //}
  1223. //waiters.push_back(requestId);
  1224. //return true;
  1225. } else {
  1226. _instance->setMainDcId(newdcWithShift);
  1227. }
  1228. } else {
  1229. newdcWithShift = ShiftDcId(newdcWithShift, GetDcIdShift(dcWithShift));
  1230. }
  1231. auto request = SerializedRequest();
  1232. {
  1233. QReadLocker locker(&_requestMapLock);
  1234. auto it = _requestMap.find(requestId);
  1235. if (it == _requestMap.cend()) {
  1236. LOG(("MTP Error: could not find request %1").arg(requestId));
  1237. return false;
  1238. }
  1239. request = it->second;
  1240. }
  1241. const auto session = getSession(newdcWithShift);
  1242. registerRequest(
  1243. requestId,
  1244. (dcWithShift < 0) ? -newdcWithShift : newdcWithShift);
  1245. session->sendPrepared(request);
  1246. return true;
  1247. } else if (type == u"MSG_WAIT_TIMEOUT"_q || type == u"MSG_WAIT_FAILED"_q) {
  1248. SerializedRequest request;
  1249. {
  1250. QReadLocker locker(&_requestMapLock);
  1251. auto it = _requestMap.find(requestId);
  1252. if (it == _requestMap.cend()) {
  1253. LOG(("MTP Error: could not find MSG_WAIT_* request %1").arg(requestId));
  1254. return false;
  1255. }
  1256. request = it->second;
  1257. }
  1258. if (!request->after) {
  1259. LOG(("MTP Error: MSG_WAIT_* for not dependent request %1").arg(requestId));
  1260. return false;
  1261. }
  1262. auto dcWithShift = ShiftedDcId(0);
  1263. if (const auto shiftedDcId = queryRequestByDc(requestId)) {
  1264. dcWithShift = *shiftedDcId;
  1265. if (const auto afterDcId = queryRequestByDc(request->after->requestId)) {
  1266. if (*shiftedDcId != *afterDcId) {
  1267. request->after = SerializedRequest();
  1268. }
  1269. } else {
  1270. request->after = SerializedRequest();
  1271. }
  1272. } else {
  1273. LOG(("MTP Error: could not find MSG_WAIT_* request %1 by dc").arg(requestId));
  1274. }
  1275. if (!dcWithShift) {
  1276. return false;
  1277. }
  1278. if (!request->after) {
  1279. getSession(qAbs(dcWithShift))->sendPrepared(request);
  1280. } else {
  1281. QMutexLocker locker(&_dependentRequestsLock);
  1282. _dependentRequests.emplace(requestId, request->after->requestId);
  1283. }
  1284. return true;
  1285. } else if (code < 0
  1286. || code >= 500
  1287. || (m1 = FloodWaitRegExp.match(type)).hasMatch()
  1288. || (m2 = FloodPremiumWaitRegExp.match(type)).hasMatch()
  1289. || ((m3 = SlowmodeWaitRegExp.match(type)).hasMatch()
  1290. && m3.captured(1).toInt() < 3)) {
  1291. if (!requestId) {
  1292. return false;
  1293. }
  1294. auto secs = 1;
  1295. auto nonPremiumDelay = false;
  1296. if (code < 0 || code >= 500) {
  1297. const auto it = _requestsDelays.find(requestId);
  1298. if (it != _requestsDelays.cend()) {
  1299. secs = (it->second > 60) ? it->second : (it->second *= 2);
  1300. } else {
  1301. _requestsDelays.emplace(requestId, secs);
  1302. }
  1303. } else if (m1.hasMatch()) {
  1304. secs = m1.captured(1).toInt();
  1305. // if (secs >= 60) return false;
  1306. } else if (m2.hasMatch()) {
  1307. secs = m2.captured(1).toInt();
  1308. nonPremiumDelay = true;
  1309. } else if (m3.hasMatch()) {
  1310. secs = m3.captured(1).toInt();
  1311. }
  1312. auto sendAt = crl::now() + secs * 1000 + 10;
  1313. auto it = _delayedRequests.begin(), e = _delayedRequests.end();
  1314. for (; it != e; ++it) {
  1315. if (it->first == requestId) {
  1316. return true;
  1317. } else if (it->second > sendAt) {
  1318. break;
  1319. }
  1320. }
  1321. _delayedRequests.insert(it, std::make_pair(requestId, sendAt));
  1322. checkDelayedRequests();
  1323. if (nonPremiumDelay) {
  1324. _nonPremiumDelayedRequests.fire_copy(requestId);
  1325. }
  1326. return true;
  1327. } else if ((code == 401 && type != u"AUTH_KEY_PERM_EMPTY"_q)
  1328. || (badGuestDc && _badGuestDcRequests.find(requestId) == _badGuestDcRequests.cend())) {
  1329. auto dcWithShift = ShiftedDcId(0);
  1330. if (const auto shiftedDcId = queryRequestByDc(requestId)) {
  1331. dcWithShift = *shiftedDcId;
  1332. } else {
  1333. LOG(("MTP Error: unauthorized request without dc info, requestId %1").arg(requestId));
  1334. }
  1335. auto newdc = BareDcId(qAbs(dcWithShift));
  1336. if (!newdc || !hasMainDcId() || newdc == mainDcId()) {
  1337. if (!badGuestDc && _globalFailHandler) {
  1338. _globalFailHandler(error, response); // auth failed in main dc
  1339. }
  1340. return false;
  1341. }
  1342. DEBUG_LOG(("MTP Info: importing auth to dcWithShift %1"
  1343. ).arg(dcWithShift));
  1344. auto &waiters(_authWaiters[newdc]);
  1345. if (!waiters.size()) {
  1346. auto exportRequestId = _instance->send(MTPauth_ExportAuthorization(
  1347. MTP_int(newdc)
  1348. ), [this](const Response &response) {
  1349. auto result = MTPauth_ExportedAuthorization();
  1350. auto from = response.reply.constData();
  1351. if (!result.read(from, from + response.reply.size())) {
  1352. return false;
  1353. }
  1354. exportDone(result, response);
  1355. return true;
  1356. }, [this](const Error &error, const Response &response) {
  1357. return exportFail(error, response);
  1358. });
  1359. _authExportRequests.emplace(exportRequestId, abs(dcWithShift));
  1360. }
  1361. waiters.push_back(requestId);
  1362. if (badGuestDc) _badGuestDcRequests.insert(requestId);
  1363. return true;
  1364. } else if (type == u"CONNECTION_NOT_INITED"_q
  1365. || type == u"CONNECTION_LAYER_INVALID"_q) {
  1366. SerializedRequest request;
  1367. {
  1368. QReadLocker locker(&_requestMapLock);
  1369. auto it = _requestMap.find(requestId);
  1370. if (it == _requestMap.cend()) {
  1371. LOG(("MTP Error: could not find request %1").arg(requestId));
  1372. return false;
  1373. }
  1374. request = it->second;
  1375. }
  1376. auto dcWithShift = ShiftedDcId(0);
  1377. if (const auto shiftedDcId = queryRequestByDc(requestId)) {
  1378. dcWithShift = *shiftedDcId;
  1379. } else {
  1380. LOG(("MTP Error: could not find request %1 for resending with init connection").arg(requestId));
  1381. }
  1382. if (!dcWithShift) return false;
  1383. const auto session = getSession(qAbs(dcWithShift));
  1384. request->needsLayer = true;
  1385. session->setConnectionNotInited();
  1386. session->sendPrepared(request);
  1387. return true;
  1388. } else if (type == u"CONNECTION_LANG_CODE_INVALID"_q) {
  1389. Lang::CurrentCloudManager().resetToDefault();
  1390. }
  1391. if (badGuestDc) _badGuestDcRequests.erase(requestId);
  1392. return false;
  1393. }
  1394. not_null<Session*> Instance::Private::getSession(
  1395. ShiftedDcId shiftedDcId) {
  1396. if (!shiftedDcId) {
  1397. Assert(_mainSession != nullptr);
  1398. return _mainSession;
  1399. } else if (!BareDcId(shiftedDcId)) {
  1400. Assert(_mainSession != nullptr);
  1401. shiftedDcId += BareDcId(_mainSession->getDcWithShift());
  1402. }
  1403. if (const auto session = findSession(shiftedDcId)) {
  1404. return session;
  1405. }
  1406. return startSession(shiftedDcId);
  1407. }
  1408. rpl::lifetime &Instance::Private::lifetime() {
  1409. return _lifetime;
  1410. }
  1411. Session *Instance::Private::findSession(ShiftedDcId shiftedDcId) {
  1412. const auto i = _sessions.find(shiftedDcId);
  1413. return (i != _sessions.end()) ? i->second.get() : nullptr;
  1414. }
  1415. not_null<Session*> Instance::Private::startSession(ShiftedDcId shiftedDcId) {
  1416. Expects(BareDcId(shiftedDcId) != 0);
  1417. const auto dc = getDcById(shiftedDcId);
  1418. const auto thread = getThreadForDc(shiftedDcId);
  1419. const auto result = _sessions.emplace(
  1420. shiftedDcId,
  1421. std::make_unique<Session>(_instance, thread, shiftedDcId, dc)
  1422. ).first->second.get();
  1423. if (isKeysDestroyer()) {
  1424. scheduleKeyDestroy(shiftedDcId);
  1425. }
  1426. return result;
  1427. }
  1428. void Instance::Private::scheduleSessionDestroy(ShiftedDcId shiftedDcId) {
  1429. const auto i = _sessions.find(shiftedDcId);
  1430. if (i == _sessions.cend()) {
  1431. return;
  1432. }
  1433. i->second->kill();
  1434. _sessionsToDestroy.push_back(std::move(i->second));
  1435. _sessions.erase(i);
  1436. InvokeQueued(_instance, [=] {
  1437. _sessionsToDestroy.clear();
  1438. });
  1439. }
  1440. not_null<QThread*> Instance::Private::getThreadForDc(
  1441. ShiftedDcId shiftedDcId) {
  1442. static const auto EnsureStarted = [](
  1443. std::unique_ptr<QThread> &thread,
  1444. auto name) {
  1445. if (!thread) {
  1446. thread = std::make_unique<QThread>();
  1447. thread->setObjectName(name());
  1448. thread->start();
  1449. }
  1450. return thread.get();
  1451. };
  1452. static const auto FindOne = [](
  1453. std::vector<std::unique_ptr<QThread>> &threads,
  1454. const char *prefix,
  1455. int index,
  1456. bool shift) {
  1457. Expects(!threads.empty());
  1458. Expects(!(threads.size() % 2));
  1459. const auto count = int(threads.size());
  1460. index %= count;
  1461. if (index >= count / 2) {
  1462. index = (count - 1) - (index - count / 2);
  1463. }
  1464. if (shift) {
  1465. index = (index + count / 2) % count;
  1466. }
  1467. return EnsureStarted(threads[index], [=] {
  1468. return QString("MTP %1 Session (%2)").arg(prefix).arg(index);
  1469. });
  1470. };
  1471. if (shiftedDcId == BareDcId(shiftedDcId)) {
  1472. return EnsureStarted(_mainSessionThread, [] {
  1473. return QString("MTP Main Session");
  1474. });
  1475. } else if (isDownloadDcId(shiftedDcId)) {
  1476. const auto index = GetDcIdShift(shiftedDcId) - kBaseDownloadDcShift;
  1477. const auto composed = index + BareDcId(shiftedDcId);
  1478. return FindOne(_fileSessionThreads, "Download", composed, false);
  1479. } else if (isUploadDcId(shiftedDcId)) {
  1480. const auto index = GetDcIdShift(shiftedDcId) - kBaseUploadDcShift;
  1481. const auto composed = index + BareDcId(shiftedDcId);
  1482. return FindOne(_fileSessionThreads, "Upload", composed, true);
  1483. }
  1484. return EnsureStarted(_otherSessionsThread, [] {
  1485. return QString("MTP Other Session");
  1486. });
  1487. }
  1488. void Instance::Private::scheduleKeyDestroy(ShiftedDcId shiftedDcId) {
  1489. Expects(isKeysDestroyer());
  1490. if (dcOptions().dcType(shiftedDcId) == DcType::Cdn) {
  1491. performKeyDestroy(shiftedDcId);
  1492. } else {
  1493. _instance->send(MTPauth_LogOut(), [=](const Response &) {
  1494. performKeyDestroy(shiftedDcId);
  1495. return true;
  1496. }, [=](const Error &error, const Response &) {
  1497. if (IsDefaultHandledError(error)) {
  1498. return false;
  1499. }
  1500. performKeyDestroy(shiftedDcId);
  1501. return true;
  1502. }, shiftedDcId);
  1503. }
  1504. }
  1505. void Instance::Private::keyWasPossiblyDestroyed(ShiftedDcId shiftedDcId) {
  1506. Expects(isKeysDestroyer());
  1507. InvokeQueued(_instance, [=] {
  1508. LOG(("MTP Info: checkIfKeyWasDestroyed on destroying key %1, "
  1509. "assuming it is destroyed.").arg(shiftedDcId));
  1510. completedKeyDestroy(shiftedDcId);
  1511. });
  1512. }
  1513. void Instance::Private::performKeyDestroy(ShiftedDcId shiftedDcId) {
  1514. Expects(isKeysDestroyer());
  1515. _instance->send(MTPDestroy_auth_key(), [=](const Response &response) {
  1516. auto result = MTPDestroyAuthKeyRes();
  1517. auto from = response.reply.constData();
  1518. if (!result.read(from, from + response.reply.size())) {
  1519. return false;
  1520. }
  1521. result.match([&](const MTPDdestroy_auth_key_ok &) {
  1522. LOG(("MTP Info: key %1 destroyed.").arg(shiftedDcId));
  1523. }, [&](const MTPDdestroy_auth_key_fail &) {
  1524. LOG(("MTP Error: key %1 destruction fail, leave it for now."
  1525. ).arg(shiftedDcId));
  1526. killSession(shiftedDcId);
  1527. }, [&](const MTPDdestroy_auth_key_none &) {
  1528. LOG(("MTP Info: key %1 already destroyed.").arg(shiftedDcId));
  1529. });
  1530. _instance->keyWasPossiblyDestroyed(shiftedDcId);
  1531. return true;
  1532. }, [=](const Error &error, const Response &response) {
  1533. LOG(("MTP Error: key %1 destruction resulted in error: %2"
  1534. ).arg(shiftedDcId).arg(error.type()));
  1535. _instance->keyWasPossiblyDestroyed(shiftedDcId);
  1536. return true;
  1537. }, shiftedDcId);
  1538. }
  1539. void Instance::Private::completedKeyDestroy(ShiftedDcId shiftedDcId) {
  1540. Expects(isKeysDestroyer());
  1541. removeDc(shiftedDcId);
  1542. _keysForWrite.erase(shiftedDcId);
  1543. killSession(shiftedDcId);
  1544. if (_dcenters.empty()) {
  1545. _allKeysDestroyed.fire({});
  1546. }
  1547. }
  1548. void Instance::Private::keyDestroyedOnServer(
  1549. ShiftedDcId shiftedDcId,
  1550. uint64 keyId) {
  1551. LOG(("Destroying key for dc: %1").arg(shiftedDcId));
  1552. if (const auto dc = findDc(BareDcId(shiftedDcId))) {
  1553. if (dc->destroyConfirmedForgottenKey(keyId)) {
  1554. LOG(("Key destroyed!"));
  1555. dcPersistentKeyChanged(BareDcId(shiftedDcId), nullptr);
  1556. } else {
  1557. LOG(("Key already is different."));
  1558. }
  1559. }
  1560. restart(shiftedDcId);
  1561. }
  1562. void Instance::Private::setUpdatesHandler(
  1563. Fn<void(const Response&)> handler) {
  1564. _updatesHandler = std::move(handler);
  1565. }
  1566. void Instance::Private::setGlobalFailHandler(
  1567. Fn<void(const Error&, const Response&)> handler) {
  1568. _globalFailHandler = std::move(handler);
  1569. }
  1570. void Instance::Private::setStateChangedHandler(
  1571. Fn<void(ShiftedDcId shiftedDcId, int32 state)> handler) {
  1572. _stateChangedHandler = std::move(handler);
  1573. }
  1574. void Instance::Private::setSessionResetHandler(
  1575. Fn<void(ShiftedDcId shiftedDcId)> handler) {
  1576. _sessionResetHandler = std::move(handler);
  1577. }
  1578. void Instance::Private::clearGlobalHandlers() {
  1579. setUpdatesHandler(nullptr);
  1580. setGlobalFailHandler(nullptr);
  1581. setStateChangedHandler(nullptr);
  1582. setSessionResetHandler(nullptr);
  1583. }
  1584. void Instance::Private::prepareToDestroy() {
  1585. // It accesses Instance in destructor, so it should be destroyed first.
  1586. _configLoader.reset();
  1587. requestCancellingDiscard();
  1588. for (const auto &[shiftedDcId, session] : base::take(_sessions)) {
  1589. session->kill();
  1590. }
  1591. _mainSession = nullptr;
  1592. auto threads = std::vector<std::unique_ptr<QThread>>();
  1593. threads.push_back(base::take(_mainSessionThread));
  1594. threads.push_back(base::take(_otherSessionsThread));
  1595. for (auto &thread : base::take(_fileSessionThreads)) {
  1596. threads.push_back(std::move(thread));
  1597. }
  1598. for (const auto &thread : threads) {
  1599. if (thread) {
  1600. thread->quit();
  1601. }
  1602. }
  1603. for (const auto &thread : threads) {
  1604. if (thread) {
  1605. thread->wait();
  1606. }
  1607. }
  1608. }
  1609. Instance::Instance(Mode mode, Fields &&fields)
  1610. : QObject()
  1611. , _private(std::make_unique<Private>(this, mode, std::move(fields))) {
  1612. _private->start();
  1613. }
  1614. void Instance::resolveProxyDomain(const QString &host) {
  1615. _private->resolveProxyDomain(host);
  1616. }
  1617. void Instance::setGoodProxyDomain(const QString &host, const QString &ip) {
  1618. _private->setGoodProxyDomain(host, ip);
  1619. }
  1620. void Instance::suggestMainDcId(DcId mainDcId) {
  1621. _private->suggestMainDcId(mainDcId);
  1622. }
  1623. void Instance::setMainDcId(DcId mainDcId) {
  1624. _private->setMainDcId(mainDcId);
  1625. }
  1626. DcId Instance::mainDcId() const {
  1627. return _private->mainDcId();
  1628. }
  1629. rpl::producer<DcId> Instance::mainDcIdValue() const {
  1630. return _private->mainDcIdValue();
  1631. }
  1632. QString Instance::systemLangCode() const {
  1633. return Lang::GetInstance().systemLangCode();
  1634. }
  1635. QString Instance::cloudLangCode() const {
  1636. return Lang::GetInstance().cloudLangCode(Lang::Pack::Current);
  1637. }
  1638. QString Instance::langPackName() const {
  1639. return Lang::GetInstance().langPackName();
  1640. }
  1641. rpl::producer<> Instance::writeKeysRequests() const {
  1642. return _private->writeKeysRequests();
  1643. }
  1644. rpl::producer<> Instance::allKeysDestroyed() const {
  1645. return _private->allKeysDestroyed();
  1646. }
  1647. void Instance::requestConfig() {
  1648. _private->requestConfig();
  1649. }
  1650. void Instance::setUserPhone(const QString &phone) {
  1651. _private->setUserPhone(phone);
  1652. }
  1653. void Instance::badConfigurationError() {
  1654. _private->badConfigurationError();
  1655. }
  1656. void Instance::syncHttpUnixtime() {
  1657. _private->syncHttpUnixtime();
  1658. }
  1659. void Instance::restartedByTimeout(ShiftedDcId shiftedDcId) {
  1660. _private->restartedByTimeout(shiftedDcId);
  1661. }
  1662. rpl::producer<ShiftedDcId> Instance::restartsByTimeout() const {
  1663. return _private->restartsByTimeout();
  1664. }
  1665. rpl::producer<mtpRequestId> Instance::nonPremiumDelayedRequests() const {
  1666. return _private->nonPremiumDelayedRequests();
  1667. }
  1668. void Instance::requestConfigIfOld() {
  1669. _private->requestConfigIfOld();
  1670. }
  1671. void Instance::requestCDNConfig() {
  1672. _private->requestCDNConfig();
  1673. }
  1674. void Instance::restart() {
  1675. _private->restart();
  1676. }
  1677. void Instance::restart(ShiftedDcId shiftedDcId) {
  1678. _private->restart(shiftedDcId);
  1679. }
  1680. int32 Instance::dcstate(ShiftedDcId shiftedDcId) {
  1681. return _private->dcstate(shiftedDcId);
  1682. }
  1683. QString Instance::dctransport(ShiftedDcId shiftedDcId) {
  1684. return _private->dctransport(shiftedDcId);
  1685. }
  1686. void Instance::ping() {
  1687. _private->ping();
  1688. }
  1689. void Instance::cancel(mtpRequestId requestId) {
  1690. _private->cancel(requestId);
  1691. }
  1692. int32 Instance::state(mtpRequestId requestId) { // < 0 means waiting for such count of ms
  1693. return _private->state(requestId);
  1694. }
  1695. void Instance::killSession(ShiftedDcId shiftedDcId) {
  1696. _private->killSession(shiftedDcId);
  1697. }
  1698. void Instance::stopSession(ShiftedDcId shiftedDcId) {
  1699. _private->stopSession(shiftedDcId);
  1700. }
  1701. void Instance::reInitConnection(DcId dcId) {
  1702. _private->reInitConnection(dcId);
  1703. }
  1704. void Instance::logout(Fn<void()> done) {
  1705. _private->logout(std::move(done));
  1706. }
  1707. void Instance::dcPersistentKeyChanged(
  1708. DcId dcId,
  1709. const AuthKeyPtr &persistentKey) {
  1710. _private->dcPersistentKeyChanged(dcId, persistentKey);
  1711. }
  1712. void Instance::dcTemporaryKeyChanged(DcId dcId) {
  1713. _private->dcTemporaryKeyChanged(dcId);
  1714. }
  1715. rpl::producer<DcId> Instance::dcTemporaryKeyChanged() const {
  1716. return _private->dcTemporaryKeyChanged();
  1717. }
  1718. AuthKeysList Instance::getKeysForWrite() const {
  1719. return _private->getKeysForWrite();
  1720. }
  1721. void Instance::addKeysForDestroy(AuthKeysList &&keys) {
  1722. _private->addKeysForDestroy(std::move(keys));
  1723. }
  1724. Config &Instance::config() const {
  1725. return _private->config();
  1726. }
  1727. const ConfigFields &Instance::configValues() const {
  1728. return _private->configValues();
  1729. }
  1730. DcOptions &Instance::dcOptions() const {
  1731. return _private->dcOptions();
  1732. }
  1733. Environment Instance::environment() const {
  1734. return _private->environment();
  1735. }
  1736. bool Instance::isTestMode() const {
  1737. return _private->isTestMode();
  1738. }
  1739. QString Instance::deviceModel() const {
  1740. return _private->deviceModel();
  1741. }
  1742. QString Instance::systemVersion() const {
  1743. return _private->systemVersion();
  1744. }
  1745. void Instance::setUpdatesHandler(Fn<void(const Response&)> handler) {
  1746. _private->setUpdatesHandler(std::move(handler));
  1747. }
  1748. void Instance::setGlobalFailHandler(
  1749. Fn<void(const Error&, const Response&)> handler) {
  1750. _private->setGlobalFailHandler(std::move(handler));
  1751. }
  1752. void Instance::setStateChangedHandler(
  1753. Fn<void(ShiftedDcId shiftedDcId, int32 state)> handler) {
  1754. _private->setStateChangedHandler(std::move(handler));
  1755. }
  1756. void Instance::setSessionResetHandler(
  1757. Fn<void(ShiftedDcId shiftedDcId)> handler) {
  1758. _private->setSessionResetHandler(std::move(handler));
  1759. }
  1760. void Instance::clearGlobalHandlers() {
  1761. _private->clearGlobalHandlers();
  1762. }
  1763. void Instance::onStateChange(ShiftedDcId shiftedDcId, int32 state) {
  1764. _private->onStateChange(shiftedDcId, state);
  1765. }
  1766. void Instance::onSessionReset(ShiftedDcId shiftedDcId) {
  1767. _private->onSessionReset(shiftedDcId);
  1768. }
  1769. bool Instance::hasCallback(mtpRequestId requestId) const {
  1770. return _private->hasCallback(requestId);
  1771. }
  1772. void Instance::processCallback(const Response &response) {
  1773. _private->processCallback(response);
  1774. }
  1775. void Instance::processUpdate(const Response &message) {
  1776. _private->processUpdate(message);
  1777. }
  1778. bool Instance::rpcErrorOccured(
  1779. const Response &response,
  1780. const FailHandler &onFail,
  1781. const Error &error) {
  1782. return _private->rpcErrorOccured(response, onFail, error);
  1783. }
  1784. bool Instance::isKeysDestroyer() const {
  1785. return _private->isKeysDestroyer();
  1786. }
  1787. void Instance::keyWasPossiblyDestroyed(ShiftedDcId shiftedDcId) {
  1788. _private->keyWasPossiblyDestroyed(shiftedDcId);
  1789. }
  1790. void Instance::keyDestroyedOnServer(ShiftedDcId shiftedDcId, uint64 keyId) {
  1791. _private->keyDestroyedOnServer(shiftedDcId, keyId);
  1792. }
  1793. void Instance::sendRequest(
  1794. mtpRequestId requestId,
  1795. SerializedRequest &&request,
  1796. ResponseHandler &&callbacks,
  1797. ShiftedDcId shiftedDcId,
  1798. crl::time msCanWait,
  1799. bool needsLayer,
  1800. mtpRequestId afterRequestId) {
  1801. return _private->sendRequest(
  1802. requestId,
  1803. std::move(request),
  1804. std::move(callbacks),
  1805. shiftedDcId,
  1806. msCanWait,
  1807. needsLayer,
  1808. afterRequestId);
  1809. }
  1810. void Instance::sendAnything(ShiftedDcId shiftedDcId, crl::time msCanWait) {
  1811. _private->getSession(shiftedDcId)->sendAnything(msCanWait);
  1812. }
  1813. rpl::lifetime &Instance::lifetime() {
  1814. return _private->lifetime();
  1815. }
  1816. Instance::~Instance() {
  1817. _private->prepareToDestroy();
  1818. }
  1819. } // namespace MTP