session_private.cpp 83 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744
  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 "base/options.h"
  8. #include "mtproto/session_private.h"
  9. #include "mtproto/details/mtproto_bound_key_creator.h"
  10. #include "mtproto/details/mtproto_dcenter.h"
  11. #include "mtproto/details/mtproto_dump_to_text.h"
  12. #include "mtproto/details/mtproto_rsa_public_key.h"
  13. #include "mtproto/session.h"
  14. #include "mtproto/mtproto_response.h"
  15. #include "mtproto/mtproto_dc_options.h"
  16. #include "mtproto/connection_abstract.h"
  17. #include "base/random.h"
  18. #include "base/qthelp_url.h"
  19. #include "base/openssl_help.h"
  20. #include "base/unixtime.h"
  21. #include "base/platform/base_platform_info.h"
  22. #include <ksandbox.h>
  23. #include <zlib.h>
  24. namespace MTP {
  25. namespace details {
  26. namespace {
  27. constexpr auto kIntSize = static_cast<int>(sizeof(mtpPrime));
  28. constexpr auto kWaitForBetterTimeout = crl::time(2000);
  29. constexpr auto kMinConnectedTimeout = crl::time(1000);
  30. constexpr auto kMaxConnectedTimeout = crl::time(8000);
  31. constexpr auto kMinReceiveTimeout = crl::time(4000);
  32. constexpr auto kMaxReceiveTimeout = crl::time(64000);
  33. constexpr auto kMarkConnectionOldTimeout = crl::time(192000);
  34. constexpr auto kPingDelayDisconnect = 60;
  35. constexpr auto kPingSendAfter = 30 * crl::time(1000);
  36. constexpr auto kPingSendAfterForce = 45 * crl::time(1000);
  37. constexpr auto kTemporaryExpiresIn = TimeId(86400);
  38. constexpr auto kBindKeyAdditionalExpiresTimeout = TimeId(30);
  39. constexpr auto kKeyOldEnoughForDestroy = 60 * crl::time(1000);
  40. constexpr auto kSentContainerLives = 600 * crl::time(1000);
  41. constexpr auto kFastRequestDuration = crl::time(500);
  42. // If we can't connect for this time we will ask _instance to update config.
  43. constexpr auto kRequestConfigTimeout = 8 * crl::time(1000);
  44. // Don't try to handle messages larger than this size.
  45. constexpr auto kMaxMessageLength = 16 * 1024 * 1024;
  46. // How much time passed from send till we resend request or check its state.
  47. constexpr auto kCheckSentRequestTimeout = 10 * crl::time(1000);
  48. // How much time to wait for some more requests,
  49. // when resending request or checking its state.
  50. constexpr auto kSendStateRequestWaiting = crl::time(1000);
  51. // How much time to wait for some more requests, when sending msg acks.
  52. constexpr auto kAckSendWaiting = 10 * crl::time(1000);
  53. constexpr auto kCutContainerOnSize = 16 * 1024;
  54. auto SyncTimeRequestDuration = kFastRequestDuration;
  55. using namespace details;
  56. [[nodiscard]] QString LogIdsVector(const QVector<MTPlong> &ids) {
  57. if (!ids.size()) return "[]";
  58. auto idsStr = QString("[%1").arg(ids.cbegin()->v);
  59. for (const auto &id : ids) {
  60. idsStr += QString(", %2").arg(id.v);
  61. }
  62. return idsStr + "]";
  63. }
  64. [[nodiscard]] QString ComputeAppVersion() {
  65. #if defined Q_OS_WIN && defined Q_PROCESSOR_X86_64
  66. const auto arch = u" x64"_q;
  67. #elif (defined Q_OS_WIN && defined Q_PROCESSOR_X86_32) || defined Q_PROCESSOR_X86_64
  68. const auto arch = QString();
  69. #else
  70. const auto arch = ' ' + QSysInfo::buildCpuArchitecture();
  71. #endif
  72. return QString::fromLatin1(AppVersionStr) + arch + ([] {
  73. #if defined OS_MAC_STORE
  74. return u" Mac App Store"_q;
  75. #elif defined OS_WIN_STORE // OS_MAC_STORE
  76. return u" Microsoft Store"_q;
  77. #else // OS_MAC_STORE || OS_WIN_STORE
  78. return KSandbox::isFlatpak()
  79. ? u" Flatpak"_q
  80. : KSandbox::isSnap()
  81. ? u" Snap"_q
  82. : QString();
  83. #endif // OS_MAC_STORE || OS_WIN_STORE
  84. })();
  85. }
  86. void WrapInvokeAfter(
  87. SerializedRequest &to,
  88. const SerializedRequest &from,
  89. const base::flat_map<mtpMsgId, SerializedRequest> &haveSent,
  90. int32 skipBeforeRequest = 0) {
  91. const auto afterId = *(mtpMsgId*)(from->after->data() + 4);
  92. const auto i = afterId ? haveSent.find(afterId) : haveSent.end();
  93. int32 size = to->size(), lenInInts = (tl::count_length(from) >> 2), headlen = 4, fulllen = headlen + lenInInts;
  94. if (i == haveSent.end()) { // no invoke after or such msg was not sent or was completed recently
  95. to->resize(size + fulllen + skipBeforeRequest);
  96. if (skipBeforeRequest) {
  97. memcpy(to->data() + size, from->constData() + 4, headlen * sizeof(mtpPrime));
  98. memcpy(to->data() + size + headlen + skipBeforeRequest, from->constData() + 4 + headlen, lenInInts * sizeof(mtpPrime));
  99. } else {
  100. memcpy(to->data() + size, from->constData() + 4, fulllen * sizeof(mtpPrime));
  101. }
  102. } else {
  103. to->resize(size + fulllen + skipBeforeRequest + 3);
  104. memcpy(to->data() + size, from->constData() + 4, headlen * sizeof(mtpPrime));
  105. (*to)[size + 3] += 3 * sizeof(mtpPrime);
  106. *((mtpTypeId*)&((*to)[size + headlen + skipBeforeRequest])) = mtpc_invokeAfterMsg;
  107. memcpy(to->data() + size + headlen + skipBeforeRequest + 1, &afterId, 2 * sizeof(mtpPrime));
  108. memcpy(to->data() + size + headlen + skipBeforeRequest + 3, from->constData() + 4 + headlen, lenInInts * sizeof(mtpPrime));
  109. if (size + 3 != 7) (*to)[7] += 3 * sizeof(mtpPrime);
  110. }
  111. }
  112. [[nodiscard]] bool ConstTimeIsDifferent(
  113. const void *a,
  114. const void *b,
  115. size_t size) {
  116. auto ca = reinterpret_cast<const char*>(a);
  117. auto cb = reinterpret_cast<const char*>(b);
  118. volatile auto different = false;
  119. for (const auto ce = ca + size; ca != ce; ++ca, ++cb) {
  120. different = different | (*ca != *cb);
  121. }
  122. return different;
  123. }
  124. base::options::toggle OptionPreferIPv6({
  125. .id = kOptionPreferIPv6,
  126. .name = "Prefer IPv6",
  127. .description = "Prefer IPv6 if it is available. Require \"Try connecting through IPv6\" to be enabled",
  128. });
  129. } // namespace
  130. const char kOptionPreferIPv6[] = "prefer-ipv6";
  131. SessionPrivate::SessionPrivate(
  132. not_null<Instance*> instance,
  133. not_null<QThread*> thread,
  134. std::shared_ptr<SessionData> data,
  135. ShiftedDcId shiftedDcId)
  136. : QObject(nullptr)
  137. , _instance(instance)
  138. , _shiftedDcId(shiftedDcId)
  139. , _realDcType(_instance->dcOptions().dcType(_shiftedDcId))
  140. , _currentDcType(_realDcType)
  141. , _state(DisconnectedState)
  142. , _retryTimer(thread, [=] { retryByTimer(); })
  143. , _oldConnectionTimer(thread, [=] { markConnectionOld(); })
  144. , _waitForConnectedTimer(thread, [=] { waitConnectedFailed(); })
  145. , _waitForReceivedTimer(thread, [=] { waitReceivedFailed(); })
  146. , _waitForBetterTimer(thread, [=] { waitBetterFailed(); })
  147. , _waitForReceived(kMinReceiveTimeout)
  148. , _waitForConnected(kMinConnectedTimeout)
  149. , _pingSender(thread, [=] { sendPingByTimer(); })
  150. , _checkSentRequestsTimer(thread, [=] { checkSentRequests(); })
  151. , _clearOldContainersTimer(thread, [=] { clearOldContainers(); })
  152. , _sessionData(std::move(data)) {
  153. Expects(_shiftedDcId != 0);
  154. moveToThread(thread);
  155. InvokeQueued(this, [=] {
  156. _clearOldContainersTimer.callEach(kSentContainerLives);
  157. connectToServer();
  158. });
  159. }
  160. SessionPrivate::~SessionPrivate() {
  161. releaseKeyCreationOnFail();
  162. doDisconnect();
  163. Expects(!_connection);
  164. Expects(_testConnections.empty());
  165. }
  166. void SessionPrivate::appendTestConnection(
  167. DcOptions::Variants::Protocol protocol,
  168. const QString &ip,
  169. int port,
  170. const bytes::vector &protocolSecret) {
  171. QWriteLocker lock(&_stateMutex);
  172. const auto priority = (qthelp::is_ipv6(ip) ? (OptionPreferIPv6.value() ? 2 : 0) : 1)
  173. + (protocol == DcOptions::Variants::Tcp ? 1 : 0)
  174. + (protocolSecret.empty() ? 0 : 1);
  175. _testConnections.push_back({
  176. AbstractConnection::Create(
  177. _instance,
  178. protocol,
  179. thread(),
  180. protocolSecret,
  181. _options->proxy),
  182. priority
  183. });
  184. const auto weak = _testConnections.back().data.get();
  185. connect(weak, &AbstractConnection::error, [=](int errorCode) {
  186. onError(weak, errorCode);
  187. });
  188. connect(weak, &AbstractConnection::receivedSome, [=] {
  189. onReceivedSome();
  190. });
  191. _firstSentAt = 0;
  192. if (_oldConnection) {
  193. _oldConnection = false;
  194. DEBUG_LOG(("This connection marked as not old!"));
  195. }
  196. _oldConnectionTimer.callOnce(kMarkConnectionOldTimeout);
  197. connect(weak, &AbstractConnection::connected, [=] {
  198. onConnected(weak);
  199. });
  200. connect(weak, &AbstractConnection::disconnected, [=] {
  201. onDisconnected(weak);
  202. });
  203. connect(weak, &AbstractConnection::syncTimeRequest, [=] {
  204. InvokeQueued(_instance, [instance = _instance] {
  205. instance->syncHttpUnixtime();
  206. });
  207. });
  208. const auto protocolForFiles = isMediaClusterDcId(_shiftedDcId)
  209. //|| isUploadDcId(_shiftedDcId)
  210. || (_realDcType == DcType::Cdn);
  211. const auto protocolDcId = getProtocolDcId();
  212. InvokeQueued(_testConnections.back().data, [=] {
  213. weak->connectToServer(
  214. ip,
  215. port,
  216. protocolSecret,
  217. protocolDcId,
  218. protocolForFiles);
  219. });
  220. }
  221. int16 SessionPrivate::getProtocolDcId() const {
  222. const auto dcId = BareDcId(_shiftedDcId);
  223. const auto simpleDcId = isTemporaryDcId(dcId)
  224. ? getRealIdFromTemporaryDcId(dcId)
  225. : dcId;
  226. const auto testedDcId = _instance->isTestMode()
  227. ? (kTestModeDcIdShift + simpleDcId)
  228. : simpleDcId;
  229. return (_currentDcType == DcType::MediaCluster)
  230. ? -testedDcId
  231. : testedDcId;
  232. }
  233. void SessionPrivate::checkSentRequests() {
  234. const auto now = crl::now();
  235. const auto checkTime = now - kCheckSentRequestTimeout;
  236. if (_bindMsgId && _bindMessageSent < checkTime) {
  237. DEBUG_LOG(("MTP Info: "
  238. "Request state while key is not bound, restarting."));
  239. restart();
  240. _checkSentRequestsTimer.callOnce(kCheckSentRequestTimeout);
  241. return;
  242. }
  243. auto requesting = false;
  244. auto nextTimeout = kCheckSentRequestTimeout;
  245. {
  246. QReadLocker locker(_sessionData->haveSentMutex());
  247. auto &haveSent = _sessionData->haveSentMap();
  248. for (const auto &[msgId, request] : haveSent) {
  249. if (request->lastSentTime <= checkTime) {
  250. // Need to check state.
  251. request->lastSentTime = now;
  252. if (_stateRequestData.emplace(msgId).second) {
  253. requesting = true;
  254. }
  255. } else {
  256. nextTimeout = std::min(request->lastSentTime - checkTime, nextTimeout);
  257. }
  258. }
  259. }
  260. if (requesting) {
  261. _sessionData->queueSendAnything(kSendStateRequestWaiting);
  262. }
  263. if (nextTimeout < kCheckSentRequestTimeout) {
  264. _checkSentRequestsTimer.callOnce(nextTimeout);
  265. }
  266. }
  267. void SessionPrivate::clearOldContainers() {
  268. auto resent = false;
  269. auto nextTimeout = kSentContainerLives;
  270. const auto now = crl::now();
  271. const auto checkTime = now - kSentContainerLives;
  272. for (auto i = _sentContainers.begin(); i != _sentContainers.end();) {
  273. if (i->second.sent <= checkTime) {
  274. DEBUG_LOG(("MTP Info: Removing old container with resending %1, "
  275. "sent: %2, now: %3, current unixtime: %4"
  276. ).arg(i->first
  277. ).arg(i->second.sent
  278. ).arg(now
  279. ).arg(base::unixtime::now()));
  280. const auto ids = std::move(i->second.messages);
  281. i = _sentContainers.erase(i);
  282. resent = resent || !ids.empty();
  283. for (const auto innerMsgId : ids) {
  284. resend(innerMsgId, -1);
  285. }
  286. } else {
  287. nextTimeout = std::min(i->second.sent - checkTime, nextTimeout);
  288. ++i;
  289. }
  290. }
  291. if (resent) {
  292. _sessionData->queueNeedToResumeAndSend();
  293. }
  294. if (nextTimeout < kSentContainerLives) {
  295. _clearOldContainersTimer.callOnce(nextTimeout);
  296. } else if (!_clearOldContainersTimer.isActive()) {
  297. _clearOldContainersTimer.callEach(nextTimeout);
  298. }
  299. }
  300. void SessionPrivate::destroyAllConnections() {
  301. clearUnboundKeyCreator();
  302. _waitForBetterTimer.cancel();
  303. _waitForReceivedTimer.cancel();
  304. _waitForConnectedTimer.cancel();
  305. _testConnections.clear();
  306. _connection = nullptr;
  307. }
  308. void SessionPrivate::cdnConfigChanged() {
  309. connectToServer(true);
  310. }
  311. int32 SessionPrivate::getShiftedDcId() const {
  312. return _shiftedDcId;
  313. }
  314. void SessionPrivate::dcOptionsChanged() {
  315. _retryTimeout = 1;
  316. connectToServer(true);
  317. }
  318. int32 SessionPrivate::getState() const {
  319. QReadLocker lock(&_stateMutex);
  320. int32 result = _state;
  321. if (_state < 0) {
  322. if (_retryTimer.isActive()) {
  323. result = int32(crl::now() - _retryWillFinish);
  324. if (result >= 0) {
  325. result = -1;
  326. }
  327. }
  328. }
  329. return result;
  330. }
  331. QString SessionPrivate::transport() const {
  332. QReadLocker lock(&_stateMutex);
  333. if (!_connection || (_state < 0)) {
  334. return QString();
  335. }
  336. Assert(_options != nullptr);
  337. return _connection->transport();
  338. }
  339. bool SessionPrivate::setState(int state, int ifState) {
  340. if (ifState != kUpdateStateAlways) {
  341. QReadLocker lock(&_stateMutex);
  342. if (_state != ifState) {
  343. return false;
  344. }
  345. }
  346. QWriteLocker lock(&_stateMutex);
  347. if (_state == state) {
  348. return false;
  349. }
  350. _state = state;
  351. if (state < 0) {
  352. _retryTimeout = -state;
  353. _retryTimer.callOnce(_retryTimeout);
  354. _retryWillFinish = crl::now() + _retryTimeout;
  355. }
  356. lock.unlock();
  357. _sessionData->queueConnectionStateChange(state);
  358. return true;
  359. }
  360. void SessionPrivate::resetSession() {
  361. MTP_LOG(_shiftedDcId, ("Resetting session!"));
  362. _needSessionReset = false;
  363. DEBUG_LOG(("MTP Info: creating new session in resetSession."));
  364. changeSessionId();
  365. _sessionData->queueResetDone();
  366. }
  367. void SessionPrivate::changeSessionId() {
  368. auto sessionId = _sessionId;
  369. do {
  370. sessionId = base::RandomValue<uint64>();
  371. } while (_sessionId == sessionId);
  372. DEBUG_LOG(("MTP Info: setting server_session: %1").arg(sessionId));
  373. _sessionId = sessionId;
  374. _messagesCounter = 0;
  375. _sessionMarkedAsStarted = false;
  376. _ackRequestData.clear();
  377. _resendRequestData.clear();
  378. _stateRequestData.clear();
  379. _receivedMessageIds.clear();
  380. }
  381. uint32 SessionPrivate::nextRequestSeqNumber(bool needAck) {
  382. const auto result = _messagesCounter;
  383. _messagesCounter += (needAck ? 1 : 0);
  384. return result * 2 + (needAck ? 1 : 0);
  385. }
  386. bool SessionPrivate::realDcTypeChanged() {
  387. const auto now = _instance->dcOptions().dcType(_shiftedDcId);
  388. if (_realDcType == now) {
  389. return false;
  390. }
  391. _realDcType = now;
  392. return true;
  393. }
  394. bool SessionPrivate::markSessionAsStarted() {
  395. if (_sessionMarkedAsStarted) {
  396. return false;
  397. }
  398. _sessionMarkedAsStarted = true;
  399. return true;
  400. }
  401. mtpMsgId SessionPrivate::prepareToSend(
  402. SerializedRequest &request,
  403. mtpMsgId currentLastId,
  404. bool forceNewMsgId) {
  405. Expects(request->size() > 8);
  406. if (const auto msgId = request.getMsgId()) {
  407. // resending this request
  408. const auto i = _resendingIds.find(msgId);
  409. if (i != _resendingIds.cend()) {
  410. _resendingIds.erase(i);
  411. }
  412. return (forceNewMsgId || msgId > currentLastId)
  413. ? replaceMsgId(request, currentLastId)
  414. : msgId;
  415. }
  416. request.setMsgId(currentLastId);
  417. request.setSeqNo(nextRequestSeqNumber(request.needAck()));
  418. if (request->requestId) {
  419. MTP_LOG(_shiftedDcId, ("[r%1] msg_id 0 -> %2").arg(request->requestId).arg(currentLastId));
  420. }
  421. return currentLastId;
  422. }
  423. mtpMsgId SessionPrivate::replaceMsgId(SerializedRequest &request, mtpMsgId newId) {
  424. Expects(request->size() > 8);
  425. const auto oldMsgId = request.getMsgId();
  426. if (oldMsgId == newId) {
  427. return newId;
  428. }
  429. // haveSentMutex() was locked in tryToSend()
  430. auto &haveSent = _sessionData->haveSentMap();
  431. while (_resendingIds.contains(newId)
  432. || _ackedIds.contains(newId)
  433. || haveSent.contains(newId)) {
  434. newId = base::unixtime::mtproto_msg_id();
  435. }
  436. MTP_LOG(_shiftedDcId, ("[r%1] msg_id %2 -> %3"
  437. ).arg(request->requestId
  438. ).arg(oldMsgId
  439. ).arg(newId));
  440. const auto i = _resendingIds.find(oldMsgId);
  441. if (i != _resendingIds.end()) {
  442. const auto requestId = i->second;
  443. _resendingIds.erase(i);
  444. _resendingIds.emplace(newId, requestId);
  445. }
  446. const auto j = _ackedIds.find(oldMsgId);
  447. if (j != _ackedIds.end()) {
  448. const auto requestId = j->second;
  449. _ackedIds.erase(j);
  450. _ackedIds.emplace(newId, requestId);
  451. }
  452. const auto k = haveSent.find(oldMsgId);
  453. if (k != haveSent.end()) {
  454. const auto request = k->second;
  455. haveSent.erase(k);
  456. haveSent.emplace(newId, request);
  457. }
  458. for (auto &[msgId, container] : _sentContainers) {
  459. for (auto &innerMsgId : container.messages) {
  460. if (innerMsgId == oldMsgId) {
  461. innerMsgId = newId;
  462. }
  463. }
  464. }
  465. request.setMsgId(newId);
  466. request.setSeqNo(nextRequestSeqNumber(request.needAck()));
  467. return newId;
  468. }
  469. mtpMsgId SessionPrivate::placeToContainer(
  470. SerializedRequest &toSendRequest,
  471. mtpMsgId &bigMsgId,
  472. bool forceNewMsgId,
  473. SerializedRequest &req) {
  474. const auto msgId = prepareToSend(req, bigMsgId, forceNewMsgId);
  475. if (msgId >= bigMsgId) {
  476. bigMsgId = base::unixtime::mtproto_msg_id();
  477. }
  478. uint32 from = toSendRequest->size(), len = req.messageSize();
  479. toSendRequest->resize(from + len);
  480. memcpy(toSendRequest->data() + from, req->constData() + 4, len * sizeof(mtpPrime));
  481. return msgId;
  482. }
  483. MTPVector<MTPJSONObjectValue> SessionPrivate::prepareInitParams() {
  484. const auto local = QDateTime::currentDateTime();
  485. const auto utc = QDateTime(local.date(), local.time(), Qt::UTC);
  486. const auto shift = base::unixtime::now() - (TimeId)::time(nullptr);
  487. const auto delta = int(utc.toSecsSinceEpoch()) - int(local.toSecsSinceEpoch()) - shift;
  488. auto sliced = delta;
  489. while (sliced < -12 * 3600) {
  490. sliced += 24 * 3600;
  491. }
  492. while (sliced > 14 * 3600) {
  493. sliced -= 24 * 3600;
  494. }
  495. const auto sign = (sliced < 0) ? -1 : 1;
  496. const auto rounded = base::SafeRound(std::abs(sliced) / 900.)
  497. * 900
  498. * sign;
  499. return MTP_vector<MTPJSONObjectValue>(
  500. 1,
  501. MTP_jsonObjectValue(
  502. MTP_string("tz_offset"),
  503. MTP_jsonNumber(MTP_double(rounded))));
  504. }
  505. void SessionPrivate::tryToSend() {
  506. DEBUG_LOG(("MTP Info: tryToSend for dc %1.").arg(_shiftedDcId));
  507. if (!_connection) {
  508. DEBUG_LOG(("MTP Info: not yet connected in dc %1.").arg(_shiftedDcId));
  509. return;
  510. } else if (!_keyId) {
  511. DEBUG_LOG(("MTP Info: not yet with auth key in dc %1.").arg(_shiftedDcId));
  512. return;
  513. }
  514. const auto needsLayer = !_sessionData->connectionInited();
  515. const auto state = getState();
  516. const auto sendOnlyFirstPing = (state != ConnectedState);
  517. const auto sendAll = !sendOnlyFirstPing && !_keyCreator;
  518. const auto isMainSession = (GetDcIdShift(_shiftedDcId) == 0);
  519. if (sendOnlyFirstPing && !_pingIdToSend) {
  520. DEBUG_LOG(("MTP Info: dc %1 not sending, waiting for Connected state, state: %2").arg(_shiftedDcId).arg(state));
  521. return; // just do nothing, if is not connected yet
  522. } else if (isMainSession
  523. && !sendOnlyFirstPing
  524. && !_pingIdToSend
  525. && !_pingId
  526. && _pingSendAt <= crl::now()) {
  527. _pingIdToSend = base::RandomValue<mtpPingId>();
  528. }
  529. const auto forceNewMsgId = sendAll && markSessionAsStarted();
  530. if (forceNewMsgId && _keyCreator) {
  531. _keyCreator->restartBinder();
  532. }
  533. auto pingRequest = SerializedRequest();
  534. auto ackRequest = SerializedRequest();
  535. auto resendRequest = SerializedRequest();
  536. auto stateRequest = SerializedRequest();
  537. auto httpWaitRequest = SerializedRequest();
  538. auto bindDcKeyRequest = SerializedRequest();
  539. if (_pingIdToSend) {
  540. if (sendOnlyFirstPing || !isMainSession) {
  541. DEBUG_LOG(("MTP Info: sending ping, ping_id: %1"
  542. ).arg(_pingIdToSend));
  543. pingRequest = SerializedRequest::Serialize(MTPPing(
  544. MTP_long(_pingIdToSend)
  545. ));
  546. } else {
  547. DEBUG_LOG(("MTP Info: sending ping_delay_disconnect, "
  548. "ping_id: %1").arg(_pingIdToSend));
  549. pingRequest = SerializedRequest::Serialize(MTPPing_delay_disconnect(
  550. MTP_long(_pingIdToSend),
  551. MTP_int(kPingDelayDisconnect)));
  552. _pingSender.callOnce(kPingSendAfterForce);
  553. }
  554. _pingSendAt = pingRequest->lastSentTime + kPingSendAfter;
  555. _pingId = base::take(_pingIdToSend);
  556. } else if (!sendAll) {
  557. DEBUG_LOG(("MTP Info: dc %1 sending only service or bind."
  558. ).arg(_shiftedDcId));
  559. } else {
  560. DEBUG_LOG(("MTP Info: dc %1 trying to send after ping, state: %2"
  561. ).arg(_shiftedDcId
  562. ).arg(state));
  563. }
  564. if (!sendOnlyFirstPing) {
  565. if (!_ackRequestData.isEmpty()) {
  566. ackRequest = SerializedRequest::Serialize(MTPMsgsAck(
  567. MTP_msgs_ack(MTP_vector<MTPlong>(
  568. base::take(_ackRequestData)))));
  569. }
  570. if (!_resendRequestData.isEmpty()) {
  571. resendRequest = SerializedRequest::Serialize(MTPMsgResendReq(
  572. MTP_msg_resend_req(MTP_vector<MTPlong>(
  573. base::take(_resendRequestData)))));
  574. }
  575. if (!_stateRequestData.empty()) {
  576. auto ids = QVector<MTPlong>();
  577. ids.reserve(_stateRequestData.size());
  578. for (const auto id : base::take(_stateRequestData)) {
  579. ids.push_back(MTP_long(id));
  580. }
  581. stateRequest = SerializedRequest::Serialize(MTPMsgsStateReq(
  582. MTP_msgs_state_req(MTP_vector<MTPlong>(ids))));
  583. }
  584. if (_connection->usingHttpWait()) {
  585. httpWaitRequest = SerializedRequest::Serialize(MTPHttpWait(
  586. MTP_http_wait(MTP_int(100), MTP_int(30), MTP_int(25000))));
  587. }
  588. if (!_bindMsgId && _keyCreator && _keyCreator->readyToBind()) {
  589. bindDcKeyRequest = _keyCreator->prepareBindRequest(
  590. _encryptionKey,
  591. _sessionId);
  592. // This is a special request with msgId used inside the message
  593. // body, so it is prepared already with a msgId and we place
  594. // seqNo for it manually here.
  595. bindDcKeyRequest.setSeqNo(
  596. nextRequestSeqNumber(bindDcKeyRequest.needAck()));
  597. }
  598. }
  599. MTPInitConnection<SerializedRequest> initWrapper;
  600. int32 initSize = 0, initSizeInInts = 0;
  601. if (needsLayer) {
  602. Assert(_options != nullptr);
  603. const auto systemLangCode = _options->systemLangCode;
  604. const auto cloudLangCode = _options->cloudLangCode;
  605. const auto langPackName = _options->langPackName;
  606. const auto deviceModel = (_currentDcType == DcType::Cdn)
  607. ? "n/a"
  608. : _instance->deviceModel();
  609. const auto systemVersion = (_currentDcType == DcType::Cdn)
  610. ? "n/a"
  611. : _instance->systemVersion();
  612. const auto appVersion = ComputeAppVersion();
  613. const auto proxyType = _options->proxy.type;
  614. const auto mtprotoProxy = (proxyType == ProxyData::Type::Mtproto);
  615. const auto clientProxyFields = mtprotoProxy
  616. ? MTP_inputClientProxy(
  617. MTP_string(_options->proxy.host),
  618. MTP_int(_options->proxy.port))
  619. : MTPInputClientProxy();
  620. using Flag = MTPInitConnection<SerializedRequest>::Flag;
  621. initWrapper = MTPInitConnection<SerializedRequest>(
  622. MTP_flags(Flag::f_params
  623. | (mtprotoProxy ? Flag::f_proxy : Flag(0))),
  624. MTP_int(ApiId),
  625. MTP_string(deviceModel),
  626. MTP_string(systemVersion),
  627. MTP_string(appVersion),
  628. MTP_string(systemLangCode),
  629. MTP_string(langPackName),
  630. MTP_string(cloudLangCode),
  631. clientProxyFields,
  632. MTP_jsonObject(prepareInitParams()),
  633. SerializedRequest());
  634. initSizeInInts = (tl::count_length(initWrapper) >> 2) + 2;
  635. initSize = initSizeInInts * sizeof(mtpPrime);
  636. }
  637. auto needAnyResponse = false;
  638. auto someSkipped = false;
  639. SerializedRequest toSendRequest;
  640. {
  641. QWriteLocker locker1(_sessionData->toSendMutex());
  642. auto scheduleCheckSentRequests = false;
  643. auto toSendDummy = base::flat_map<mtpRequestId, SerializedRequest>();
  644. auto &toSend = sendAll
  645. ? _sessionData->toSendMap()
  646. : toSendDummy;
  647. if (!sendAll) {
  648. locker1.unlock();
  649. }
  650. auto totalSending = int(toSend.size());
  651. auto sendingFrom = begin(toSend);
  652. auto sendingTill = end(toSend);
  653. auto combinedLength = 0;
  654. for (auto i = sendingFrom; i != sendingTill; ++i) {
  655. combinedLength += i->second->size();
  656. if (combinedLength >= kCutContainerOnSize) {
  657. ++i;
  658. if (const auto skipping = int(sendingTill - i)) {
  659. sendingTill = i;
  660. totalSending -= skipping;
  661. Assert(totalSending > 0);
  662. someSkipped = true;
  663. }
  664. break;
  665. }
  666. }
  667. auto sendingRange = ranges::make_subrange(sendingFrom, sendingTill);
  668. const auto sendingCount = totalSending;
  669. if (pingRequest) ++totalSending;
  670. if (ackRequest) ++totalSending;
  671. if (resendRequest) ++totalSending;
  672. if (stateRequest) ++totalSending;
  673. if (httpWaitRequest) ++totalSending;
  674. if (bindDcKeyRequest) ++totalSending;
  675. if (!totalSending) {
  676. return; // nothing to send
  677. }
  678. const auto first = pingRequest
  679. ? pingRequest
  680. : ackRequest
  681. ? ackRequest
  682. : resendRequest
  683. ? resendRequest
  684. : stateRequest
  685. ? stateRequest
  686. : httpWaitRequest
  687. ? httpWaitRequest
  688. : bindDcKeyRequest
  689. ? bindDcKeyRequest
  690. : sendingRange.begin()->second;
  691. if (totalSending == 1 && !first->forceSendInContainer) {
  692. toSendRequest = first;
  693. if (sendAll) {
  694. toSend.erase(sendingFrom, sendingTill);
  695. locker1.unlock();
  696. }
  697. const auto msgId = prepareToSend(
  698. toSendRequest,
  699. base::unixtime::mtproto_msg_id(),
  700. forceNewMsgId && !bindDcKeyRequest);
  701. if (bindDcKeyRequest) {
  702. _bindMsgId = msgId;
  703. _bindMessageSent = crl::now();
  704. needAnyResponse = true;
  705. } else if (pingRequest) {
  706. _pingMsgId = msgId;
  707. needAnyResponse = true;
  708. } else if (stateRequest || resendRequest) {
  709. _stateAndResendRequests.emplace(
  710. msgId,
  711. stateRequest ? stateRequest : resendRequest);
  712. needAnyResponse = true;
  713. }
  714. if (toSendRequest->requestId) {
  715. if (toSendRequest.needAck()) {
  716. toSendRequest->lastSentTime = crl::now();
  717. QWriteLocker locker2(_sessionData->haveSentMutex());
  718. auto &haveSent = _sessionData->haveSentMap();
  719. haveSent.emplace(msgId, toSendRequest);
  720. scheduleCheckSentRequests = true;
  721. const auto wrapLayer = needsLayer && toSendRequest->needsLayer;
  722. if (toSendRequest->after) {
  723. const auto toSendSize = tl::count_length(toSendRequest) >> 2;
  724. auto wrappedRequest = SerializedRequest::Prepare(
  725. toSendSize,
  726. toSendSize + 3);
  727. wrappedRequest->resize(4);
  728. memcpy(wrappedRequest->data(), toSendRequest->constData(), 4 * sizeof(mtpPrime));
  729. WrapInvokeAfter(wrappedRequest, toSendRequest, haveSent);
  730. toSendRequest = std::move(wrappedRequest);
  731. }
  732. if (wrapLayer) {
  733. const auto noWrapSize = (tl::count_length(toSendRequest) >> 2);
  734. const auto toSendSize = noWrapSize + initSizeInInts;
  735. auto wrappedRequest = SerializedRequest::Prepare(toSendSize);
  736. memcpy(wrappedRequest->data(), toSendRequest->constData(), 7 * sizeof(mtpPrime)); // all except length
  737. wrappedRequest->push_back(mtpc_invokeWithLayer);
  738. wrappedRequest->push_back(kCurrentLayer);
  739. initWrapper.write<mtpBuffer>(*wrappedRequest);
  740. wrappedRequest->resize(wrappedRequest->size() + noWrapSize);
  741. memcpy(wrappedRequest->data() + wrappedRequest->size() - noWrapSize, toSendRequest->constData() + 8, noWrapSize * sizeof(mtpPrime));
  742. toSendRequest = std::move(wrappedRequest);
  743. }
  744. needAnyResponse = true;
  745. } else {
  746. _ackedIds.emplace(msgId, toSendRequest->requestId);
  747. }
  748. }
  749. } else { // send in container
  750. bool willNeedInit = false;
  751. uint32 containerSize = 1 + 1; // cons + vector size
  752. if (pingRequest) containerSize += pingRequest.messageSize();
  753. if (ackRequest) containerSize += ackRequest.messageSize();
  754. if (resendRequest) containerSize += resendRequest.messageSize();
  755. if (stateRequest) containerSize += stateRequest.messageSize();
  756. if (httpWaitRequest) containerSize += httpWaitRequest.messageSize();
  757. if (bindDcKeyRequest) containerSize += bindDcKeyRequest.messageSize();
  758. for (const auto &[requestId, request] : sendingRange) {
  759. containerSize += request.messageSize();
  760. if (needsLayer && request->needsLayer) {
  761. containerSize += initSizeInInts;
  762. willNeedInit = true;
  763. }
  764. }
  765. mtpBuffer initSerialized;
  766. if (willNeedInit) {
  767. initSerialized.reserve(initSizeInInts);
  768. initSerialized.push_back(mtpc_invokeWithLayer);
  769. initSerialized.push_back(kCurrentLayer);
  770. initWrapper.write<mtpBuffer>(initSerialized);
  771. }
  772. // prepare container + each in invoke after
  773. toSendRequest = SerializedRequest::Prepare(
  774. containerSize,
  775. containerSize + 3 * sendingCount);
  776. toSendRequest->push_back(mtpc_msg_container);
  777. toSendRequest->push_back(totalSending);
  778. // check for a valid container
  779. auto bigMsgId = base::unixtime::mtproto_msg_id();
  780. // the fact of this lock is used in replaceMsgId()
  781. QWriteLocker locker2(_sessionData->haveSentMutex());
  782. auto &haveSent = _sessionData->haveSentMap();
  783. // prepare sent container
  784. auto sentIdsWrap = SentContainer();
  785. sentIdsWrap.sent = crl::now();
  786. sentIdsWrap.messages.reserve(totalSending);
  787. if (bindDcKeyRequest) {
  788. _bindMsgId = placeToContainer(
  789. toSendRequest,
  790. bigMsgId,
  791. false,
  792. bindDcKeyRequest);
  793. _bindMessageSent = crl::now();
  794. sentIdsWrap.messages.push_back(_bindMsgId);
  795. needAnyResponse = true;
  796. }
  797. if (pingRequest) {
  798. _pingMsgId = placeToContainer(
  799. toSendRequest,
  800. bigMsgId,
  801. forceNewMsgId,
  802. pingRequest);
  803. sentIdsWrap.messages.push_back(_pingMsgId);
  804. needAnyResponse = true;
  805. }
  806. for (auto &[requestId, request] : sendingRange) {
  807. const auto msgId = prepareToSend(
  808. request,
  809. bigMsgId,
  810. forceNewMsgId);
  811. if (msgId >= bigMsgId) {
  812. bigMsgId = base::unixtime::mtproto_msg_id();
  813. }
  814. bool added = false;
  815. if (request->requestId) {
  816. if (request.needAck()) {
  817. request->lastSentTime = crl::now();
  818. int32 reqNeedsLayer = (needsLayer && request->needsLayer) ? toSendRequest->size() : 0;
  819. if (request->after) {
  820. WrapInvokeAfter(toSendRequest, request, haveSent, reqNeedsLayer ? initSizeInInts : 0);
  821. if (reqNeedsLayer) {
  822. memcpy(toSendRequest->data() + reqNeedsLayer + 4, initSerialized.constData(), initSize);
  823. *(toSendRequest->data() + reqNeedsLayer + 3) += initSize;
  824. }
  825. added = true;
  826. } else if (reqNeedsLayer) {
  827. toSendRequest->resize(reqNeedsLayer + initSizeInInts + request.messageSize());
  828. memcpy(toSendRequest->data() + reqNeedsLayer, request->constData() + 4, 4 * sizeof(mtpPrime));
  829. memcpy(toSendRequest->data() + reqNeedsLayer + 4, initSerialized.constData(), initSize);
  830. memcpy(toSendRequest->data() + reqNeedsLayer + 4 + initSizeInInts, request->constData() + 8, tl::count_length(request));
  831. *(toSendRequest->data() + reqNeedsLayer + 3) += initSize;
  832. added = true;
  833. }
  834. // #TODO rewrite so that it will always hold.
  835. //Assert(!haveSent.contains(msgId));
  836. haveSent.emplace(msgId, request);
  837. sentIdsWrap.messages.push_back(msgId);
  838. scheduleCheckSentRequests = true;
  839. needAnyResponse = true;
  840. } else {
  841. _ackedIds.emplace(msgId, request->requestId);
  842. }
  843. }
  844. if (!added) {
  845. uint32 from = toSendRequest->size(), len = request.messageSize();
  846. toSendRequest->resize(from + len);
  847. memcpy(toSendRequest->data() + from, request->constData() + 4, len * sizeof(mtpPrime));
  848. }
  849. }
  850. toSend.erase(sendingFrom, sendingTill);
  851. if (stateRequest) {
  852. const auto msgId = placeToContainer(
  853. toSendRequest,
  854. bigMsgId,
  855. forceNewMsgId,
  856. stateRequest);
  857. _stateAndResendRequests.emplace(msgId, stateRequest);
  858. needAnyResponse = true;
  859. }
  860. if (resendRequest) {
  861. const auto msgId = placeToContainer(
  862. toSendRequest,
  863. bigMsgId,
  864. forceNewMsgId,
  865. resendRequest);
  866. _stateAndResendRequests.emplace(msgId, resendRequest);
  867. needAnyResponse = true;
  868. }
  869. if (ackRequest) {
  870. placeToContainer(
  871. toSendRequest,
  872. bigMsgId,
  873. forceNewMsgId,
  874. ackRequest);
  875. }
  876. if (httpWaitRequest) {
  877. placeToContainer(
  878. toSendRequest,
  879. bigMsgId,
  880. forceNewMsgId,
  881. httpWaitRequest);
  882. }
  883. const auto containerMsgId = prepareToSend(
  884. toSendRequest,
  885. bigMsgId,
  886. forceNewMsgId);
  887. _sentContainers.emplace(containerMsgId, std::move(sentIdsWrap));
  888. if (scheduleCheckSentRequests && !_checkSentRequestsTimer.isActive()) {
  889. _checkSentRequestsTimer.callOnce(kCheckSentRequestTimeout);
  890. }
  891. }
  892. }
  893. sendSecureRequest(std::move(toSendRequest), needAnyResponse);
  894. if (someSkipped) {
  895. InvokeQueued(this, [=] {
  896. tryToSend();
  897. });
  898. }
  899. }
  900. void SessionPrivate::retryByTimer() {
  901. if (_retryTimeout < 3) {
  902. ++_retryTimeout;
  903. } else if (_retryTimeout == 3) {
  904. _retryTimeout = 1000;
  905. } else if (_retryTimeout < 64000) {
  906. _retryTimeout *= 2;
  907. }
  908. connectToServer();
  909. }
  910. void SessionPrivate::restartNow() {
  911. _retryTimeout = 1;
  912. _retryTimer.cancel();
  913. restart();
  914. }
  915. void SessionPrivate::connectToServer(bool afterConfig) {
  916. if (afterConfig && (!_testConnections.empty() || _connection)) {
  917. return;
  918. }
  919. destroyAllConnections();
  920. if (realDcTypeChanged() && _keyCreator) {
  921. destroyTemporaryKey();
  922. return;
  923. }
  924. _options = std::make_unique<SessionOptions>(_sessionData->options());
  925. const auto bareDc = BareDcId(_shiftedDcId);
  926. _currentDcType = tryAcquireKeyCreation();
  927. if (_currentDcType == DcType::Cdn && !_instance->isKeysDestroyer()) {
  928. if (!_instance->dcOptions().hasCDNKeysForDc(bareDc)) {
  929. requestCDNConfig();
  930. return;
  931. }
  932. }
  933. if (_options->proxy.type == ProxyData::Type::Mtproto) {
  934. // host, port, secret for mtproto proxy are taken from proxy.
  935. appendTestConnection(DcOptions::Variants::Tcp, {}, 0, {});
  936. } else {
  937. using Variants = DcOptions::Variants;
  938. const auto special = (_currentDcType == DcType::Temporary);
  939. const auto variants = _instance->dcOptions().lookup(
  940. bareDc,
  941. _currentDcType,
  942. _options->proxy.type != ProxyData::Type::None);
  943. const auto useIPv4 = special ? true : _options->useIPv4;
  944. const auto useIPv6 = special ? false : _options->useIPv6;
  945. const auto useTcp = special ? true : _options->useTcp;
  946. const auto useHttp = special ? false : _options->useHttp;
  947. const auto skipAddress = !useIPv4
  948. ? Variants::IPv4
  949. : !useIPv6
  950. ? Variants::IPv6
  951. : Variants::AddressTypeCount;
  952. const auto skipProtocol = !useTcp
  953. ? Variants::Tcp
  954. : !useHttp
  955. ? Variants::Http
  956. : Variants::ProtocolCount;
  957. for (auto address = 0; address != Variants::AddressTypeCount; ++address) {
  958. if (address == skipAddress) {
  959. continue;
  960. }
  961. for (auto protocol = 0; protocol != Variants::ProtocolCount; ++protocol) {
  962. if (protocol == skipProtocol) {
  963. continue;
  964. }
  965. for (const auto &endpoint : variants.data[address][protocol]) {
  966. appendTestConnection(
  967. static_cast<Variants::Protocol>(protocol),
  968. QString::fromStdString(endpoint.ip),
  969. endpoint.port,
  970. endpoint.secret);
  971. }
  972. }
  973. }
  974. }
  975. if (_testConnections.empty()) {
  976. if (_instance->isKeysDestroyer()) {
  977. LOG(("MTP Error: DC %1 options for not found for auth key destruction!").arg(_shiftedDcId));
  978. _instance->keyWasPossiblyDestroyed(_shiftedDcId);
  979. return;
  980. } else if (afterConfig) {
  981. LOG(("MTP Error: DC %1 options for not found right after config load!").arg(_shiftedDcId));
  982. return restart();
  983. }
  984. DEBUG_LOG(("MTP Info: DC %1 options not found, waiting for config").arg(_shiftedDcId));
  985. InvokeQueued(_instance, [instance = _instance] {
  986. instance->requestConfig();
  987. });
  988. return;
  989. }
  990. DEBUG_LOG(("Connection Info: Connecting to %1 with %2 test connections."
  991. ).arg(_shiftedDcId
  992. ).arg(_testConnections.size()));
  993. if (!_startedConnectingAt) {
  994. _startedConnectingAt = crl::now();
  995. } else if (crl::now() - _startedConnectingAt > kRequestConfigTimeout) {
  996. InvokeQueued(_instance, [instance = _instance] {
  997. instance->requestConfigIfOld();
  998. });
  999. }
  1000. _retryTimer.cancel();
  1001. _waitForConnectedTimer.cancel();
  1002. setState(ConnectingState);
  1003. _bindMsgId = 0;
  1004. _pingId = _pingMsgId = _pingIdToSend = _pingSendAt = 0;
  1005. _pingSender.cancel();
  1006. _waitForConnectedTimer.callOnce(_waitForConnected);
  1007. }
  1008. void SessionPrivate::restart() {
  1009. DEBUG_LOG(("MTP Info: restarting Connection"));
  1010. _waitForReceivedTimer.cancel();
  1011. _waitForConnectedTimer.cancel();
  1012. doDisconnect();
  1013. if (_needSessionReset) {
  1014. resetSession();
  1015. }
  1016. if (_retryTimer.isActive()) {
  1017. return;
  1018. }
  1019. DEBUG_LOG(("MTP Info: restart timeout: %1ms").arg(_retryTimeout));
  1020. setState(-_retryTimeout);
  1021. }
  1022. void SessionPrivate::onSentSome(uint64 size) {
  1023. if (!_waitForReceivedTimer.isActive()) {
  1024. auto remain = static_cast<uint64>(_waitForReceived);
  1025. if (!_oldConnection) {
  1026. // 8kb / sec, so 512 kb give 64 sec
  1027. auto remainBySize = size * _waitForReceived / 8192;
  1028. remain = std::clamp(
  1029. remainBySize,
  1030. remain,
  1031. uint64(kMaxReceiveTimeout));
  1032. if (remain != _waitForReceived) {
  1033. DEBUG_LOG(("Checking connect for request with size %1 bytes, delay will be %2").arg(size).arg(remain));
  1034. }
  1035. }
  1036. _waitForReceivedTimer.callOnce(remain);
  1037. }
  1038. if (!_firstSentAt) {
  1039. _firstSentAt = crl::now();
  1040. }
  1041. }
  1042. void SessionPrivate::onReceivedSome() {
  1043. if (_oldConnection) {
  1044. _oldConnection = false;
  1045. DEBUG_LOG(("This connection marked as not old!"));
  1046. }
  1047. _oldConnectionTimer.callOnce(kMarkConnectionOldTimeout);
  1048. _waitForReceivedTimer.cancel();
  1049. if (_firstSentAt > 0) {
  1050. const auto ms = crl::now() - _firstSentAt;
  1051. DEBUG_LOG(("MTP Info: response in %1ms, _waitForReceived: %2ms"
  1052. ).arg(ms
  1053. ).arg(_waitForReceived));
  1054. if (ms > 0 && ms * 2 < _waitForReceived) {
  1055. _waitForReceived = qMax(ms * 2, kMinReceiveTimeout);
  1056. }
  1057. _firstSentAt = -1;
  1058. }
  1059. }
  1060. void SessionPrivate::markConnectionOld() {
  1061. _oldConnection = true;
  1062. _waitForReceived = kMinReceiveTimeout;
  1063. DEBUG_LOG(("This connection marked as old! _waitForReceived now %1ms"
  1064. ).arg(_waitForReceived));
  1065. }
  1066. void SessionPrivate::sendPingByTimer() {
  1067. if (_pingId) {
  1068. // _pingSendAt: when to send next ping (lastPingAt + kPingSendAfter)
  1069. // could be equal to zero.
  1070. const auto now = crl::now();
  1071. const auto mustSendTill = _pingSendAt
  1072. + kPingSendAfterForce
  1073. - kPingSendAfter;
  1074. if (mustSendTill < now + 1000) {
  1075. LOG(("Could not send ping for some seconds, restarting..."));
  1076. return restart();
  1077. } else {
  1078. _pingSender.callOnce(mustSendTill - now);
  1079. }
  1080. } else {
  1081. _sessionData->queueNeedToResumeAndSend();
  1082. }
  1083. }
  1084. void SessionPrivate::sendPingForce() {
  1085. DEBUG_LOG(("MTP Info: send ping force for dcWithShift %1.").arg(_shiftedDcId));
  1086. if (!_pingId) {
  1087. _pingSendAt = 0;
  1088. DEBUG_LOG(("Will send ping!"));
  1089. tryToSend();
  1090. }
  1091. }
  1092. void SessionPrivate::waitReceivedFailed() {
  1093. Expects(_options != nullptr);
  1094. DEBUG_LOG(("MTP Info: bad connection, _waitForReceived: %1ms").arg(_waitForReceived));
  1095. if (_waitForReceived < kMaxReceiveTimeout) {
  1096. _waitForReceived *= 2;
  1097. }
  1098. doDisconnect();
  1099. if (_retryTimer.isActive()) {
  1100. return;
  1101. }
  1102. DEBUG_LOG(("MTP Info: immediate restart!"));
  1103. InvokeQueued(this, [=] { connectToServer(); });
  1104. const auto instance = _instance;
  1105. const auto shiftedDcId = _shiftedDcId;
  1106. InvokeQueued(instance, [=] {
  1107. instance->restartedByTimeout(shiftedDcId);
  1108. });
  1109. }
  1110. void SessionPrivate::waitConnectedFailed() {
  1111. DEBUG_LOG(("MTP Info: can't connect in %1ms").arg(_waitForConnected));
  1112. auto maxTimeout = kMaxConnectedTimeout;
  1113. for (const auto &connection : _testConnections) {
  1114. accumulate_max(maxTimeout, connection.data->fullConnectTimeout());
  1115. }
  1116. if (_waitForConnected < maxTimeout) {
  1117. _waitForConnected = std::min(maxTimeout, 2 * _waitForConnected);
  1118. }
  1119. connectingTimedOut();
  1120. DEBUG_LOG(("MTP Info: immediate restart!"));
  1121. InvokeQueued(this, [=] { connectToServer(); });
  1122. }
  1123. void SessionPrivate::waitBetterFailed() {
  1124. confirmBestConnection();
  1125. }
  1126. void SessionPrivate::connectingTimedOut() {
  1127. for (const auto &connection : _testConnections) {
  1128. connection.data->timedOut();
  1129. }
  1130. doDisconnect();
  1131. }
  1132. void SessionPrivate::doDisconnect() {
  1133. destroyAllConnections();
  1134. setState(DisconnectedState);
  1135. }
  1136. void SessionPrivate::requestCDNConfig() {
  1137. InvokeQueued(_instance, [instance = _instance] {
  1138. instance->requestCDNConfig();
  1139. });
  1140. }
  1141. void SessionPrivate::handleReceived() {
  1142. Expects(_encryptionKey != nullptr);
  1143. onReceivedSome();
  1144. while (!_connection->received().empty()) {
  1145. auto intsBuffer = std::move(_connection->received().front());
  1146. _connection->received().pop_front();
  1147. constexpr auto kExternalHeaderIntsCount = 6U; // 2 auth_key_id, 4 msg_key
  1148. constexpr auto kEncryptedHeaderIntsCount = 8U; // 2 salt, 2 session, 2 msg_id, 1 seq_no, 1 length
  1149. constexpr auto kMinimalEncryptedIntsCount = kEncryptedHeaderIntsCount + 4U; // + 1 data + 3 padding
  1150. constexpr auto kMinimalIntsCount = kExternalHeaderIntsCount + kMinimalEncryptedIntsCount;
  1151. auto intsCount = uint32(intsBuffer.size());
  1152. auto ints = intsBuffer.constData();
  1153. if ((intsCount < kMinimalIntsCount) || (intsCount > kMaxMessageLength / kIntSize)) {
  1154. LOG(("TCP Error: bad message received, len %1").arg(intsCount * kIntSize));
  1155. return restart();
  1156. }
  1157. if (_keyId != *(uint64*)ints) {
  1158. LOG(("TCP Error: bad auth_key_id %1 instead of %2 received").arg(_keyId).arg(*(uint64*)ints));
  1159. return restart();
  1160. }
  1161. constexpr auto kMinPaddingSize = 12U;
  1162. constexpr auto kMaxPaddingSize = 1024U;
  1163. auto encryptedInts = ints + kExternalHeaderIntsCount;
  1164. auto encryptedIntsCount = (intsCount - kExternalHeaderIntsCount) & ~0x03U;
  1165. auto encryptedBytesCount = encryptedIntsCount * kIntSize;
  1166. auto decryptedBuffer = QByteArray(encryptedBytesCount, Qt::Uninitialized);
  1167. auto msgKey = *(MTPint128*)(ints + 2);
  1168. aesIgeDecrypt(encryptedInts, decryptedBuffer.data(), encryptedBytesCount, _encryptionKey, msgKey);
  1169. auto decryptedInts = reinterpret_cast<const mtpPrime*>(decryptedBuffer.constData());
  1170. auto serverSalt = *(uint64*)&decryptedInts[0];
  1171. auto session = *(uint64*)&decryptedInts[2];
  1172. auto msgId = *(uint64*)&decryptedInts[4];
  1173. auto seqNo = *(uint32*)&decryptedInts[6];
  1174. auto needAck = ((seqNo & 0x01) != 0);
  1175. auto messageLength = *(uint32*)&decryptedInts[7];
  1176. auto fullDataLength = kEncryptedHeaderIntsCount * kIntSize + messageLength; // Without padding.
  1177. // Can underflow, but it is an unsigned type, so we just check the range later.
  1178. auto paddingSize = static_cast<uint32>(encryptedBytesCount) - static_cast<uint32>(fullDataLength);
  1179. std::array<uchar, 32> sha256Buffer = { { 0 } };
  1180. SHA256_CTX msgKeyLargeContext;
  1181. SHA256_Init(&msgKeyLargeContext);
  1182. SHA256_Update(&msgKeyLargeContext, _encryptionKey->partForMsgKey(false), 32);
  1183. SHA256_Update(&msgKeyLargeContext, decryptedInts, encryptedBytesCount);
  1184. SHA256_Final(sha256Buffer.data(), &msgKeyLargeContext);
  1185. constexpr auto kMsgKeyShift = 8U;
  1186. if (ConstTimeIsDifferent(&msgKey, sha256Buffer.data() + kMsgKeyShift, sizeof(msgKey))) {
  1187. LOG(("TCP Error: bad SHA256 hash after aesDecrypt in message"));
  1188. return restart();
  1189. }
  1190. if ((messageLength > kMaxMessageLength)
  1191. || (messageLength & 0x03)
  1192. || (paddingSize < kMinPaddingSize)
  1193. || (paddingSize > kMaxPaddingSize)) {
  1194. LOG(("TCP Error: bad msg_len received %1, data size: %2").arg(messageLength).arg(encryptedBytesCount));
  1195. return restart();
  1196. }
  1197. if (Logs::DebugEnabled()) {
  1198. _connection->logInfo(u"Decrypted message %1,%2,%3 is %4 len"_q
  1199. .arg(msgId)
  1200. .arg(seqNo)
  1201. .arg(Logs::b(needAck))
  1202. .arg(fullDataLength));
  1203. }
  1204. if (session != _sessionId) {
  1205. LOG(("MTP Error: bad server session received"));
  1206. return restart();
  1207. }
  1208. const auto serverTime = int32(msgId >> 32);
  1209. const auto isReply = ((msgId & 0x03) == 1);
  1210. if (!isReply && ((msgId & 0x03) != 3)) {
  1211. LOG(("MTP Error: bad msg_id %1 in message received").arg(msgId));
  1212. return restart();
  1213. }
  1214. const auto clientTime = base::unixtime::now();
  1215. const auto badTime = (serverTime > clientTime + 60)
  1216. || (serverTime + 300 < clientTime);
  1217. if (badTime) {
  1218. DEBUG_LOG(("MTP Info: bad server time from msg_id: %1, my time: %2").arg(serverTime).arg(clientTime));
  1219. }
  1220. bool wasConnected = (getState() == ConnectedState);
  1221. if (serverSalt != _sessionSalt) {
  1222. if (!badTime) {
  1223. DEBUG_LOG(("MTP Info: other salt received... received: %1, my salt: %2, updating...").arg(serverSalt).arg(_sessionSalt));
  1224. _sessionSalt = serverSalt;
  1225. if (setState(ConnectedState, ConnectingState)) {
  1226. resendAll();
  1227. }
  1228. } else {
  1229. DEBUG_LOG(("MTP Info: other salt received... received: %1, my salt: %2").arg(serverSalt).arg(_sessionSalt));
  1230. }
  1231. } else {
  1232. serverSalt = 0; // dont pass to handle method, so not to lock in setSalt()
  1233. }
  1234. if (needAck) _ackRequestData.push_back(MTP_long(msgId));
  1235. auto res = HandleResult::Success; // if no need to handle, then succeed
  1236. auto from = decryptedInts + kEncryptedHeaderIntsCount;
  1237. auto end = from + (messageLength / kIntSize);
  1238. auto sfrom = decryptedInts + 4U; // msg_id + seq_no + length + message
  1239. MTP_LOG(_shiftedDcId, ("Recv: ")
  1240. + DumpToText(sfrom, end)
  1241. + QString(" (dc:%1,key:%2)"
  1242. ).arg(AbstractConnection::ProtocolDcDebugId(getProtocolDcId())
  1243. ).arg(_encryptionKey->keyId()));
  1244. const auto registered = _receivedMessageIds.registerMsgId(
  1245. msgId,
  1246. needAck);
  1247. if (registered == ReceivedIdsManager::Result::Success) {
  1248. res = handleOneReceived(from, end, msgId, {
  1249. .outerMsgId = msgId,
  1250. .serverSalt = serverSalt,
  1251. .serverTime = serverTime,
  1252. .badTime = badTime,
  1253. });
  1254. } else if (registered == ReceivedIdsManager::Result::TooOld) {
  1255. res = HandleResult::ResetSession;
  1256. }
  1257. _receivedMessageIds.shrink();
  1258. // send acks
  1259. if (const auto toAckSize = _ackRequestData.size()) {
  1260. DEBUG_LOG(("MTP Info: will send %1 acks, ids: %2").arg(toAckSize).arg(LogIdsVector(_ackRequestData)));
  1261. _sessionData->queueSendAnything(kAckSendWaiting);
  1262. }
  1263. auto lock = QReadLocker(_sessionData->haveReceivedMutex());
  1264. const auto tryToReceive = !_sessionData->haveReceivedMessages().empty();
  1265. lock.unlock();
  1266. if (tryToReceive) {
  1267. DEBUG_LOG(("MTP Info: queueTryToReceive() - need to parse in another thread, %1 messages.").arg(_sessionData->haveReceivedMessages().size()));
  1268. _sessionData->queueTryToReceive();
  1269. }
  1270. if (res != HandleResult::Success && res != HandleResult::Ignored) {
  1271. if (res == HandleResult::DestroyTemporaryKey) {
  1272. destroyTemporaryKey();
  1273. } else if (res == HandleResult::ResetSession) {
  1274. _needSessionReset = true;
  1275. }
  1276. return restart();
  1277. }
  1278. _retryTimeout = 1; // reset restart() timer
  1279. _startedConnectingAt = crl::time(0);
  1280. if (!wasConnected) {
  1281. if (getState() == ConnectedState) {
  1282. _sessionData->queueNeedToResumeAndSend();
  1283. }
  1284. }
  1285. }
  1286. if (_connection->needHttpWait()) {
  1287. _sessionData->queueSendAnything();
  1288. }
  1289. }
  1290. SessionPrivate::HandleResult SessionPrivate::handleOneReceived(
  1291. const mtpPrime *from,
  1292. const mtpPrime *end,
  1293. uint64 msgId,
  1294. OuterInfo info) {
  1295. Expects(from < end);
  1296. switch (mtpTypeId(*from)) {
  1297. case mtpc_gzip_packed: {
  1298. DEBUG_LOG(("Message Info: gzip container"));
  1299. mtpBuffer response = ungzip(++from, end);
  1300. if (response.empty()) {
  1301. return HandleResult::RestartConnection;
  1302. }
  1303. return handleOneReceived(response.data(), response.data() + response.size(), msgId, info);
  1304. }
  1305. case mtpc_msg_container: {
  1306. if (++from >= end) {
  1307. return HandleResult::ParseError;
  1308. }
  1309. const mtpPrime *otherEnd;
  1310. const auto msgsCount = (uint32)*(from++);
  1311. DEBUG_LOG(("Message Info: container received, count: %1").arg(msgsCount));
  1312. for (uint32 i = 0; i < msgsCount; ++i) {
  1313. if (from + 4 >= end) {
  1314. return HandleResult::ParseError;
  1315. }
  1316. otherEnd = from + 4;
  1317. MTPlong inMsgId;
  1318. if (!inMsgId.read(from, otherEnd)) {
  1319. return HandleResult::ParseError;
  1320. }
  1321. bool isReply = ((inMsgId.v & 0x03) == 1);
  1322. if (!isReply && ((inMsgId.v & 0x03) != 3)) {
  1323. LOG(("Message Error: bad msg_id %1 in contained message received").arg(inMsgId.v));
  1324. return HandleResult::RestartConnection;
  1325. }
  1326. MTPint inSeqNo;
  1327. if (!inSeqNo.read(from, otherEnd)) {
  1328. return HandleResult::ParseError;
  1329. }
  1330. MTPint bytes;
  1331. if (!bytes.read(from, otherEnd)) {
  1332. return HandleResult::ParseError;
  1333. }
  1334. if ((bytes.v & 0x03) || bytes.v < 4) {
  1335. LOG(("Message Error: bad length %1 of contained message received").arg(bytes.v));
  1336. return HandleResult::RestartConnection;
  1337. }
  1338. bool needAck = (inSeqNo.v & 0x01);
  1339. if (needAck) _ackRequestData.push_back(inMsgId);
  1340. DEBUG_LOG(("Message Info: message from container, msg_id: %1, needAck: %2").arg(inMsgId.v).arg(Logs::b(needAck)));
  1341. otherEnd = from + (bytes.v >> 2);
  1342. if (otherEnd > end) {
  1343. return HandleResult::ParseError;
  1344. }
  1345. auto res = HandleResult::Success; // if no need to handle, then succeed
  1346. const auto registered = _receivedMessageIds.registerMsgId(
  1347. inMsgId.v,
  1348. needAck);
  1349. if (registered == ReceivedIdsManager::Result::Success) {
  1350. res = handleOneReceived(from, otherEnd, inMsgId.v, info);
  1351. info.badTime = false;
  1352. } else if (registered == ReceivedIdsManager::Result::TooOld) {
  1353. res = HandleResult::ResetSession;
  1354. }
  1355. if (res != HandleResult::Success) {
  1356. return res;
  1357. }
  1358. from = otherEnd;
  1359. }
  1360. } return HandleResult::Success;
  1361. case mtpc_msgs_ack: {
  1362. MTPMsgsAck msg;
  1363. if (!msg.read(from, end)) {
  1364. return HandleResult::ParseError;
  1365. }
  1366. const auto &ids = msg.c_msgs_ack().vmsg_ids().v;
  1367. DEBUG_LOG(("Message Info: acks received, ids: %1"
  1368. ).arg(LogIdsVector(ids)));
  1369. if (ids.isEmpty()) {
  1370. return info.badTime ? HandleResult::Ignored : HandleResult::Success;
  1371. }
  1372. if (info.badTime) {
  1373. if (!requestsFixTimeSalt(ids, info)) {
  1374. return HandleResult::Ignored;
  1375. }
  1376. } else {
  1377. correctUnixtimeByFastRequest(ids, info.serverTime);
  1378. }
  1379. requestsAcked(ids);
  1380. } return HandleResult::Success;
  1381. case mtpc_bad_msg_notification: {
  1382. MTPBadMsgNotification msg;
  1383. if (!msg.read(from, end)) {
  1384. return HandleResult::ParseError;
  1385. }
  1386. const auto &data(msg.c_bad_msg_notification());
  1387. LOG(("Message Info: bad message notification received (error_code %3) for msg_id = %1, seq_no = %2").arg(data.vbad_msg_id().v).arg(data.vbad_msg_seqno().v).arg(data.verror_code().v));
  1388. const auto resendId = data.vbad_msg_id().v;
  1389. const auto errorCode = data.verror_code().v;
  1390. if (false
  1391. || errorCode == 16
  1392. || errorCode == 17
  1393. || errorCode == 32
  1394. || errorCode == 33
  1395. || errorCode == 64) { // can handle
  1396. const auto needResend = false
  1397. || (errorCode == 16) // bad msg_id
  1398. || (errorCode == 17) // bad msg_id
  1399. || (errorCode == 64); // bad container
  1400. if (errorCode == 64) { // bad container!
  1401. if (Logs::DebugEnabled()) {
  1402. const auto i = _sentContainers.find(resendId);
  1403. if (i == _sentContainers.end()) {
  1404. LOG(("Message Error: Container not found!"));
  1405. } else {
  1406. auto idsList = QStringList();
  1407. for (const auto innerMsgId : i->second.messages) {
  1408. idsList.push_back(QString::number(innerMsgId));
  1409. }
  1410. LOG(("Message Info: bad container received! messages: %1").arg(idsList.join(',')));
  1411. }
  1412. }
  1413. }
  1414. if (!wasSent(resendId)) {
  1415. DEBUG_LOG(("Message Error: "
  1416. "such message was not sent recently %1").arg(resendId));
  1417. return info.badTime
  1418. ? HandleResult::Ignored
  1419. : HandleResult::Success;
  1420. }
  1421. if (needResend) { // bad msg_id or bad container
  1422. if (info.serverSalt) {
  1423. _sessionSalt = info.serverSalt;
  1424. }
  1425. correctUnixtimeWithBadLocal(info.serverTime);
  1426. DEBUG_LOG(("Message Info: unixtime updated, now %1, resending in container...").arg(info.serverTime));
  1427. resend(resendId);
  1428. } else { // must create new session, because msg_id and msg_seqno are inconsistent
  1429. if (info.badTime) {
  1430. if (info.serverSalt) {
  1431. _sessionSalt = info.serverSalt;
  1432. }
  1433. correctUnixtimeWithBadLocal(info.serverTime);
  1434. info.badTime = false;
  1435. }
  1436. if (_bindMsgId) {
  1437. LOG(("Message Info: bad message notification received"
  1438. " while binding temp key, restarting."));
  1439. return HandleResult::RestartConnection;
  1440. }
  1441. LOG(("Message Info: bad message notification received, msgId %1, error_code %2").arg(data.vbad_msg_id().v).arg(errorCode));
  1442. return HandleResult::ResetSession;
  1443. }
  1444. } else { // fatal (except 48, but it must not get here)
  1445. const auto badMsgId = mtpMsgId(data.vbad_msg_id().v);
  1446. const auto requestId = wasSent(resendId);
  1447. if (_bindMsgId) {
  1448. LOG(("Message Error: fatal bad message notification received"
  1449. " while binding temp key, restarting."));
  1450. return HandleResult::RestartConnection;
  1451. } else if (requestId) {
  1452. LOG(("Message Error: "
  1453. "fatal bad message notification received, "
  1454. "msgId %1, error_code %2, requestId: %3"
  1455. ).arg(badMsgId
  1456. ).arg(errorCode
  1457. ).arg(requestId));
  1458. auto reply = mtpBuffer();
  1459. MTPRpcError(MTP_rpc_error(
  1460. MTP_int(500),
  1461. MTP_string("PROTOCOL_ERROR")
  1462. )).write(reply);
  1463. // Save rpc_error for processing in the main thread.
  1464. QWriteLocker locker(_sessionData->haveReceivedMutex());
  1465. _sessionData->haveReceivedMessages().push_back({
  1466. .reply = std::move(reply),
  1467. .outerMsgId = info.outerMsgId,
  1468. .requestId = requestId,
  1469. });
  1470. } else {
  1471. DEBUG_LOG(("Message Error: "
  1472. "such message was not sent recently %1").arg(badMsgId));
  1473. }
  1474. return info.badTime
  1475. ? HandleResult::Ignored
  1476. : HandleResult::Success;
  1477. }
  1478. } return HandleResult::Success;
  1479. case mtpc_bad_server_salt: {
  1480. MTPBadMsgNotification msg;
  1481. if (!msg.read(from, end)) {
  1482. return HandleResult::ParseError;
  1483. }
  1484. const auto &data = msg.c_bad_server_salt();
  1485. DEBUG_LOG(("Message Info: bad server salt received (error_code %4) for msg_id = %1, seq_no = %2, new salt: %3").arg(data.vbad_msg_id().v).arg(data.vbad_msg_seqno().v).arg(data.vnew_server_salt().v).arg(data.verror_code().v));
  1486. const auto resendId = data.vbad_msg_id().v;
  1487. if (!wasSent(resendId)) {
  1488. DEBUG_LOG(("Message Error: such message was not sent recently %1").arg(resendId));
  1489. return (info.badTime ? HandleResult::Ignored : HandleResult::Success);
  1490. }
  1491. _sessionSalt = data.vnew_server_salt().v;
  1492. // Don't force time update here.
  1493. base::unixtime::update(info.serverTime);
  1494. if (_bindMsgId) {
  1495. LOG(("Message Info: bad_server_salt received while binding temp key, restarting."));
  1496. return HandleResult::RestartConnection;
  1497. }
  1498. if (setState(ConnectedState, ConnectingState)) {
  1499. resendAll();
  1500. }
  1501. info.badTime = false;
  1502. DEBUG_LOG(("Message Info: unixtime updated, now %1, server_salt updated, now %2, resending...").arg(info.serverTime).arg(info.serverSalt));
  1503. resend(resendId);
  1504. } return HandleResult::Success;
  1505. case mtpc_msgs_state_info: {
  1506. MTPMsgsStateInfo msg;
  1507. if (!msg.read(from, end)) {
  1508. return HandleResult::ParseError;
  1509. }
  1510. auto &data = msg.c_msgs_state_info();
  1511. auto reqMsgId = data.vreq_msg_id().v;
  1512. auto &states = data.vinfo().v;
  1513. DEBUG_LOG(("Message Info: msg state received, msgId %1, reqMsgId: %2, HEX states %3").arg(msgId).arg(reqMsgId).arg(Logs::mb(states.data(), states.length()).str()));
  1514. const auto i = _stateAndResendRequests.find(reqMsgId);
  1515. if (i == _stateAndResendRequests.end()) {
  1516. DEBUG_LOG(("Message Error: such message was not sent recently %1").arg(reqMsgId));
  1517. return info.badTime
  1518. ? HandleResult::Ignored
  1519. : HandleResult::Success;
  1520. }
  1521. if (info.badTime) {
  1522. if (info.serverSalt) {
  1523. _sessionSalt = info.serverSalt; // requestsFixTimeSalt with no lookup
  1524. }
  1525. correctUnixtimeWithBadLocal(info.serverTime);
  1526. DEBUG_LOG(("Message Info: unixtime updated from mtpc_msgs_state_info, now %1").arg(info.serverTime));
  1527. info.badTime = false;
  1528. }
  1529. const auto originalRequest = i->second;
  1530. Assert(originalRequest->size() > 8);
  1531. requestsAcked(QVector<MTPlong>(1, MTP_long(reqMsgId)), true);
  1532. auto rFrom = originalRequest->constData() + 8;
  1533. const auto rEnd = originalRequest->constData() + originalRequest->size();
  1534. if (mtpTypeId(*rFrom) == mtpc_msgs_state_req) {
  1535. MTPMsgsStateReq request;
  1536. if (!request.read(rFrom, rEnd)) {
  1537. LOG(("Message Error: could not parse sent msgs_state_req"));
  1538. return HandleResult::ParseError;
  1539. }
  1540. handleMsgsStates(request.c_msgs_state_req().vmsg_ids().v, states);
  1541. } else {
  1542. MTPMsgResendReq request;
  1543. if (!request.read(rFrom, rEnd)) {
  1544. LOG(("Message Error: could not parse sent msgs_resend_req"));
  1545. return HandleResult::ParseError;
  1546. }
  1547. handleMsgsStates(request.c_msg_resend_req().vmsg_ids().v, states);
  1548. }
  1549. } return HandleResult::Success;
  1550. case mtpc_msgs_all_info: {
  1551. if (info.badTime) {
  1552. DEBUG_LOG(("Message Info: skipping with bad time..."));
  1553. return HandleResult::Ignored;
  1554. }
  1555. MTPMsgsAllInfo msg;
  1556. if (!msg.read(from, end)) {
  1557. return HandleResult::ParseError;
  1558. }
  1559. auto &data = msg.c_msgs_all_info();
  1560. auto &ids = data.vmsg_ids().v;
  1561. auto &states = data.vinfo().v;
  1562. DEBUG_LOG(("Message Info: msgs all info received, msgId %1, reqMsgIds: %2, states %3").arg(
  1563. QString::number(msgId),
  1564. LogIdsVector(ids),
  1565. Logs::mb(states.data(), states.length()).str()));
  1566. handleMsgsStates(ids, states);
  1567. } return HandleResult::Success;
  1568. case mtpc_msg_detailed_info: {
  1569. MTPMsgDetailedInfo msg;
  1570. if (!msg.read(from, end)) {
  1571. return HandleResult::ParseError;
  1572. }
  1573. const auto &data(msg.c_msg_detailed_info());
  1574. DEBUG_LOG(("Message Info: msg detailed info, sent msgId %1, answerId %2, status %3, bytes %4").arg(data.vmsg_id().v).arg(data.vanswer_msg_id().v).arg(data.vstatus().v).arg(data.vbytes().v));
  1575. QVector<MTPlong> ids(1, data.vmsg_id());
  1576. if (info.badTime) {
  1577. if (requestsFixTimeSalt(ids, info)) {
  1578. info.badTime = false;
  1579. } else {
  1580. DEBUG_LOG(("Message Info: error, such message was not sent recently %1").arg(data.vmsg_id().v));
  1581. return HandleResult::Ignored;
  1582. }
  1583. }
  1584. requestsAcked(ids);
  1585. const auto resMsgId = data.vanswer_msg_id();
  1586. if (_receivedMessageIds.lookup(resMsgId.v) != ReceivedIdsManager::State::NotFound) {
  1587. _ackRequestData.push_back(resMsgId);
  1588. } else {
  1589. DEBUG_LOG(("Message Info: answer message %1 was not received, requesting...").arg(resMsgId.v));
  1590. _resendRequestData.push_back(resMsgId);
  1591. }
  1592. } return HandleResult::Success;
  1593. case mtpc_msg_new_detailed_info: {
  1594. if (info.badTime) {
  1595. DEBUG_LOG(("Message Info: skipping msg_new_detailed_info with bad time..."));
  1596. return HandleResult::Ignored;
  1597. }
  1598. MTPMsgDetailedInfo msg;
  1599. if (!msg.read(from, end)) {
  1600. return HandleResult::ParseError;
  1601. }
  1602. const auto &data(msg.c_msg_new_detailed_info());
  1603. DEBUG_LOG(("Message Info: msg new detailed info, answerId %2, status %3, bytes %4").arg(data.vanswer_msg_id().v).arg(data.vstatus().v).arg(data.vbytes().v));
  1604. const auto resMsgId = data.vanswer_msg_id();
  1605. if (_receivedMessageIds.lookup(resMsgId.v) != ReceivedIdsManager::State::NotFound) {
  1606. _ackRequestData.push_back(resMsgId);
  1607. } else {
  1608. DEBUG_LOG(("Message Info: answer message %1 was not received, requesting...").arg(resMsgId.v));
  1609. _resendRequestData.push_back(resMsgId);
  1610. }
  1611. } return HandleResult::Success;
  1612. case mtpc_rpc_result: {
  1613. if (from + 3 > end) {
  1614. return HandleResult::ParseError;
  1615. }
  1616. auto response = mtpBuffer();
  1617. MTPlong reqMsgId;
  1618. if (!reqMsgId.read(++from, end)) {
  1619. return HandleResult::ParseError;
  1620. }
  1621. const auto requestMsgId = reqMsgId.v;
  1622. DEBUG_LOG(("RPC Info: response received for %1, queueing...").arg(requestMsgId));
  1623. QVector<MTPlong> ids(1, reqMsgId);
  1624. if (info.badTime) {
  1625. if (requestsFixTimeSalt(ids, info)) {
  1626. info.badTime = false;
  1627. } else {
  1628. DEBUG_LOG(("Message Info: error, such message was not sent recently %1").arg(requestMsgId));
  1629. return HandleResult::Ignored;
  1630. }
  1631. }
  1632. mtpTypeId typeId = from[0];
  1633. if (typeId == mtpc_gzip_packed) {
  1634. DEBUG_LOG(("RPC Info: gzip container"));
  1635. response = ungzip(++from, end);
  1636. if (response.empty()) {
  1637. return HandleResult::RestartConnection;
  1638. }
  1639. typeId = response[0];
  1640. } else {
  1641. response.resize(end - from);
  1642. memcpy(response.data(), from, (end - from) * sizeof(mtpPrime));
  1643. }
  1644. if (typeId == mtpc_rpc_error) {
  1645. if (IsDestroyedTemporaryKeyError(response)) {
  1646. return HandleResult::DestroyTemporaryKey;
  1647. }
  1648. // An error could be some RPC_CALL_FAIL or other error inside
  1649. // the initConnection, so we're not sure yet that it was inited.
  1650. // Wait till a good response is received.
  1651. } else {
  1652. _sessionData->notifyConnectionInited(*_options);
  1653. }
  1654. requestsAcked(ids, true);
  1655. const auto bindResult = handleBindResponse(requestMsgId, response);
  1656. if (bindResult != HandleResult::Ignored) {
  1657. return bindResult;
  1658. }
  1659. const auto requestId = wasSent(requestMsgId);
  1660. if (requestId && requestId != mtpRequestId(0xFFFFFFFF)) {
  1661. // Save rpc_result for processing in the main thread.
  1662. QWriteLocker locker(_sessionData->haveReceivedMutex());
  1663. _sessionData->haveReceivedMessages().push_back({
  1664. .reply = std::move(response),
  1665. .outerMsgId = info.outerMsgId,
  1666. .requestId = requestId,
  1667. });
  1668. } else {
  1669. DEBUG_LOG(("RPC Info: requestId not found for msgId %1").arg(requestMsgId));
  1670. }
  1671. } return HandleResult::Success;
  1672. case mtpc_new_session_created: {
  1673. const mtpPrime *start = from;
  1674. MTPNewSession msg;
  1675. if (!msg.read(from, end)) {
  1676. return HandleResult::ParseError;
  1677. }
  1678. const auto &data(msg.c_new_session_created());
  1679. if (info.badTime) {
  1680. if (requestsFixTimeSalt(QVector<MTPlong>(1, data.vfirst_msg_id()), info)) {
  1681. info.badTime = false;
  1682. } else {
  1683. DEBUG_LOG(("Message Info: error, such message was not sent recently %1").arg(data.vfirst_msg_id().v));
  1684. return HandleResult::Ignored;
  1685. }
  1686. }
  1687. DEBUG_LOG(("Message Info: new server session created, unique_id %1, first_msg_id %2, server_salt %3").arg(data.vunique_id().v).arg(data.vfirst_msg_id().v).arg(data.vserver_salt().v));
  1688. _sessionSalt = data.vserver_salt().v;
  1689. mtpMsgId firstMsgId = data.vfirst_msg_id().v;
  1690. QVector<quint64> toResend;
  1691. {
  1692. QReadLocker locker(_sessionData->haveSentMutex());
  1693. const auto &haveSent = _sessionData->haveSentMap();
  1694. toResend.reserve(haveSent.size());
  1695. for (const auto &[msgId, request] : haveSent) {
  1696. if (msgId >= firstMsgId) {
  1697. break;
  1698. } else if (request->requestId) {
  1699. toResend.push_back(msgId);
  1700. }
  1701. }
  1702. }
  1703. for (const auto msgId : toResend) {
  1704. resend(msgId, 10);
  1705. }
  1706. mtpBuffer update(from - start);
  1707. if (from > start) memcpy(update.data(), start, (from - start) * sizeof(mtpPrime));
  1708. // Notify main process about new session - need to get difference.
  1709. QWriteLocker locker(_sessionData->haveReceivedMutex());
  1710. _sessionData->haveReceivedMessages().push_back({
  1711. .reply = update,
  1712. .outerMsgId = info.outerMsgId,
  1713. });
  1714. } return HandleResult::Success;
  1715. case mtpc_pong: {
  1716. MTPPong msg;
  1717. if (!msg.read(from, end)) {
  1718. return HandleResult::ParseError;
  1719. }
  1720. const auto &data(msg.c_pong());
  1721. DEBUG_LOG(("Message Info: pong received, msg_id: %1, ping_id: %2").arg(data.vmsg_id().v).arg(data.vping_id().v));
  1722. if (!wasSent(data.vmsg_id().v)) {
  1723. DEBUG_LOG(("Message Error: such msg_id %1 ping_id %2 was not sent recently").arg(data.vmsg_id().v).arg(data.vping_id().v));
  1724. return HandleResult::Ignored;
  1725. }
  1726. if (data.vping_id().v == _pingId) {
  1727. _pingId = 0;
  1728. } else {
  1729. DEBUG_LOG(("Message Info: just pong..."));
  1730. }
  1731. QVector<MTPlong> ids(1, data.vmsg_id());
  1732. if (info.badTime) {
  1733. if (requestsFixTimeSalt(ids, info)) {
  1734. info.badTime = false;
  1735. } else {
  1736. return HandleResult::Ignored;
  1737. }
  1738. }
  1739. requestsAcked(ids, true);
  1740. } return HandleResult::Success;
  1741. }
  1742. if (info.badTime) {
  1743. DEBUG_LOG(("Message Error: bad time in updates cons, must create new session"));
  1744. return HandleResult::ResetSession;
  1745. }
  1746. if (_currentDcType == DcType::Regular) {
  1747. mtpBuffer update(end - from);
  1748. if (end > from) {
  1749. memcpy(update.data(), from, (end - from) * sizeof(mtpPrime));
  1750. }
  1751. // Notify main process about the new updates.
  1752. QWriteLocker locker(_sessionData->haveReceivedMutex());
  1753. _sessionData->haveReceivedMessages().push_back({
  1754. .reply = update,
  1755. .outerMsgId = info.outerMsgId,
  1756. });
  1757. } else {
  1758. LOG(("Message Error: unexpected updates in dcType: %1"
  1759. ).arg(static_cast<int>(_currentDcType)));
  1760. }
  1761. return HandleResult::Success;
  1762. }
  1763. SessionPrivate::HandleResult SessionPrivate::handleBindResponse(
  1764. mtpMsgId requestMsgId,
  1765. const mtpBuffer &response) {
  1766. if (!_keyCreator || !_bindMsgId || _bindMsgId != requestMsgId) {
  1767. return HandleResult::Ignored;
  1768. }
  1769. _bindMsgId = 0;
  1770. const auto result = _keyCreator->handleBindResponse(response);
  1771. switch (result) {
  1772. case DcKeyBindState::Success:
  1773. if (!_sessionData->releaseKeyCreationOnDone(
  1774. _encryptionKey,
  1775. base::take(_keyCreator)->bindPersistentKey())) {
  1776. return HandleResult::DestroyTemporaryKey;
  1777. }
  1778. _sessionData->queueNeedToResumeAndSend();
  1779. return HandleResult::Success;
  1780. case DcKeyBindState::DefinitelyDestroyed:
  1781. if (destroyOldEnoughPersistentKey()) {
  1782. return HandleResult::DestroyTemporaryKey;
  1783. }
  1784. [[fallthrough]];
  1785. case DcKeyBindState::Failed:
  1786. _sessionData->queueNeedToResumeAndSend();
  1787. return HandleResult::Success;
  1788. }
  1789. Unexpected("Result of BoundKeyCreator::handleBindResponse.");
  1790. }
  1791. mtpBuffer SessionPrivate::ungzip(const mtpPrime *from, const mtpPrime *end) const {
  1792. mtpBuffer result; // * 4 because of mtpPrime type
  1793. result.resize(0);
  1794. MTPstring packed;
  1795. if (!packed.read(from, end)) { // read packed string as serialized mtp string type
  1796. LOG(("RPC Error: could not read gziped bytes."));
  1797. return result;
  1798. }
  1799. uint32 packedLen = packed.v.size(), unpackedChunk = packedLen;
  1800. z_stream stream;
  1801. stream.zalloc = 0;
  1802. stream.zfree = 0;
  1803. stream.opaque = 0;
  1804. stream.avail_in = 0;
  1805. stream.next_in = 0;
  1806. int res = inflateInit2(&stream, 16 + MAX_WBITS);
  1807. if (res != Z_OK) {
  1808. LOG(("RPC Error: could not init zlib stream, code: %1").arg(res));
  1809. return result;
  1810. }
  1811. stream.avail_in = packedLen;
  1812. stream.next_in = reinterpret_cast<Bytef*>(packed.v.data());
  1813. stream.avail_out = 0;
  1814. while (!stream.avail_out) {
  1815. result.resize(result.size() + unpackedChunk);
  1816. stream.avail_out = unpackedChunk * sizeof(mtpPrime);
  1817. stream.next_out = (Bytef*)&result[result.size() - unpackedChunk];
  1818. int res = inflate(&stream, Z_NO_FLUSH);
  1819. if (res != Z_OK && res != Z_STREAM_END) {
  1820. inflateEnd(&stream);
  1821. LOG(("RPC Error: could not unpack gziped data, code: %1").arg(res));
  1822. DEBUG_LOG(("RPC Error: bad gzip: %1").arg(Logs::mb(packed.v.constData(), packedLen).str()));
  1823. return mtpBuffer();
  1824. }
  1825. }
  1826. if (stream.avail_out & 0x03) {
  1827. uint32 badSize = result.size() * sizeof(mtpPrime) - stream.avail_out;
  1828. LOG(("RPC Error: bad length of unpacked data %1").arg(badSize));
  1829. DEBUG_LOG(("RPC Error: bad unpacked data %1").arg(Logs::mb(result.data(), badSize).str()));
  1830. return mtpBuffer();
  1831. }
  1832. result.resize(result.size() - (stream.avail_out >> 2));
  1833. inflateEnd(&stream);
  1834. if (!result.size()) {
  1835. LOG(("RPC Error: bad length of unpacked data 0"));
  1836. }
  1837. return result;
  1838. }
  1839. bool SessionPrivate::requestsFixTimeSalt(const QVector<MTPlong> &ids, const OuterInfo &info) {
  1840. for (const auto &id : ids) {
  1841. if (wasSent(id.v)) {
  1842. // Found such msg_id in recent acked or in recent sent requests.
  1843. if (info.serverSalt) {
  1844. _sessionSalt = info.serverSalt;
  1845. }
  1846. correctUnixtimeWithBadLocal(info.serverTime);
  1847. return true;
  1848. }
  1849. }
  1850. return false;
  1851. }
  1852. void SessionPrivate::correctUnixtimeByFastRequest(
  1853. const QVector<MTPlong> &ids,
  1854. TimeId serverTime) {
  1855. const auto now = crl::now();
  1856. QReadLocker locker(_sessionData->haveSentMutex());
  1857. const auto &haveSent = _sessionData->haveSentMap();
  1858. for (const auto &id : ids) {
  1859. const auto i = haveSent.find(id.v);
  1860. if (i == haveSent.end()) {
  1861. continue;
  1862. }
  1863. const auto duration = (now - i->second->lastSentTime);
  1864. if (duration < 0 || duration > SyncTimeRequestDuration) {
  1865. continue;
  1866. }
  1867. locker.unlock();
  1868. SyncTimeRequestDuration = duration;
  1869. base::unixtime::update(serverTime);
  1870. return;
  1871. }
  1872. }
  1873. void SessionPrivate::correctUnixtimeWithBadLocal(TimeId serverTime) {
  1874. SyncTimeRequestDuration = kFastRequestDuration;
  1875. base::unixtime::update(serverTime, true);
  1876. }
  1877. void SessionPrivate::requestsAcked(const QVector<MTPlong> &ids, bool byResponse) {
  1878. DEBUG_LOG(("Message Info: requests acked, ids %1").arg(LogIdsVector(ids)));
  1879. QVector<MTPlong> toAckMore;
  1880. {
  1881. QWriteLocker locker2(_sessionData->haveSentMutex());
  1882. auto &haveSent = _sessionData->haveSentMap();
  1883. for (const auto &wrappedMsgId : ids) {
  1884. const auto msgId = wrappedMsgId.v;
  1885. if (const auto i = _sentContainers.find(msgId); i != end(_sentContainers)) {
  1886. DEBUG_LOG(("Message Info: container ack received, msgId %1").arg(msgId));
  1887. const auto &list = i->second.messages;
  1888. toAckMore.reserve(toAckMore.size() + list.size());
  1889. for (const auto msgId : list) {
  1890. toAckMore.push_back(MTP_long(msgId));
  1891. }
  1892. _sentContainers.erase(i);
  1893. continue;
  1894. }
  1895. if (const auto i = _stateAndResendRequests.find(msgId); i != end(_stateAndResendRequests)) {
  1896. _stateAndResendRequests.erase(i);
  1897. continue;
  1898. }
  1899. if (const auto i = haveSent.find(msgId); i != end(haveSent)) {
  1900. const auto requestId = i->second->requestId;
  1901. if (!byResponse && _instance->hasCallback(requestId)) {
  1902. DEBUG_LOG(("Message Info: ignoring ACK for msgId %1 because request %2 requires a response").arg(msgId).arg(requestId));
  1903. continue;
  1904. }
  1905. haveSent.erase(i);
  1906. _ackedIds.emplace(msgId, requestId);
  1907. continue;
  1908. }
  1909. DEBUG_LOG(("Message Info: msgId %1 was not found in recent sent, while acking requests, searching in resend...").arg(msgId));
  1910. if (const auto i = _resendingIds.find(msgId); i != end(_resendingIds)) {
  1911. const auto requestId = i->second;
  1912. if (!byResponse && _instance->hasCallback(requestId)) {
  1913. DEBUG_LOG(("Message Info: ignoring ACK for msgId %1 because request %2 requires a response").arg(msgId).arg(requestId));
  1914. continue;
  1915. }
  1916. _resendingIds.erase(i);
  1917. QWriteLocker locker4(_sessionData->toSendMutex());
  1918. auto &toSend = _sessionData->toSendMap();
  1919. const auto j = toSend.find(requestId);
  1920. if (j == end(toSend)) {
  1921. DEBUG_LOG(("Message Info: msgId %1 was found in recent resent, requestId %2 was not found in prepared to send").arg(msgId).arg(requestId));
  1922. continue;
  1923. }
  1924. if (j->second->requestId != requestId) {
  1925. DEBUG_LOG(("Message Error: for msgId %1 found resent request, requestId %2, contains requestId %3").arg(msgId).arg(requestId).arg(j->second->requestId));
  1926. } else {
  1927. DEBUG_LOG(("Message Info: acked msgId %1 that was prepared to resend, requestId %2").arg(msgId).arg(requestId));
  1928. }
  1929. _ackedIds.emplace(msgId, j->second->requestId);
  1930. toSend.erase(j);
  1931. continue;
  1932. }
  1933. DEBUG_LOG(("Message Info: msgId %1 was not found in recent resent either").arg(msgId));
  1934. }
  1935. }
  1936. auto ackedCount = _ackedIds.size();
  1937. if (ackedCount > kIdsBufferSize) {
  1938. DEBUG_LOG(("Message Info: removing some old acked sent msgIds %1").arg(ackedCount - kIdsBufferSize));
  1939. while (ackedCount-- > kIdsBufferSize) {
  1940. _ackedIds.erase(_ackedIds.begin());
  1941. }
  1942. }
  1943. if (toAckMore.size()) {
  1944. requestsAcked(toAckMore);
  1945. }
  1946. }
  1947. void SessionPrivate::handleMsgsStates(const QVector<MTPlong> &ids, const QByteArray &states) {
  1948. const auto idsCount = ids.size();
  1949. if (!idsCount) {
  1950. DEBUG_LOG(("Message Info: void ids vector in handleMsgsStates()"));
  1951. return;
  1952. }
  1953. if (states.size() != idsCount) {
  1954. LOG(("Message Error: got less states than required ids count."));
  1955. return;
  1956. }
  1957. auto acked = QVector<MTPlong>();
  1958. acked.reserve(idsCount);
  1959. for (auto i = 0; i != idsCount; ++i) {
  1960. const auto state = states[i];
  1961. const auto requestMsgId = ids[i].v;
  1962. {
  1963. QReadLocker locker(_sessionData->haveSentMutex());
  1964. if (!_sessionData->haveSentMap().contains(requestMsgId)) {
  1965. DEBUG_LOG(("Message Info: state was received for msgId %1, but request is not found, looking in resent requests...").arg(requestMsgId));
  1966. const auto reqIt = _resendingIds.find(requestMsgId);
  1967. if (reqIt != _resendingIds.cend()) {
  1968. if ((state & 0x07) != 0x04) { // was received
  1969. DEBUG_LOG(("Message Info: state was received for msgId %1, state %2, already resending in container").arg(requestMsgId).arg((int32)state));
  1970. } else {
  1971. DEBUG_LOG(("Message Info: state was received for msgId %1, state %2, ack, cancelling resend").arg(requestMsgId).arg((int32)state));
  1972. acked.push_back(MTP_long(requestMsgId)); // will remove from resend in requestsAcked
  1973. }
  1974. } else {
  1975. DEBUG_LOG(("Message Info: msgId %1 was not found in recent resent either").arg(requestMsgId));
  1976. }
  1977. continue;
  1978. }
  1979. }
  1980. if ((state & 0x07) != 0x04) { // was received
  1981. DEBUG_LOG(("Message Info: state was received for msgId %1, state %2, resending in container").arg(requestMsgId).arg((int32)state));
  1982. resend(requestMsgId, 10);
  1983. } else {
  1984. DEBUG_LOG(("Message Info: state was received for msgId %1, state %2, ack").arg(requestMsgId).arg((int32)state));
  1985. acked.push_back(MTP_long(requestMsgId));
  1986. }
  1987. }
  1988. requestsAcked(acked);
  1989. }
  1990. void SessionPrivate::clearSpecialMsgId(mtpMsgId msgId) {
  1991. if (msgId == _pingMsgId) {
  1992. _pingMsgId = 0;
  1993. _pingId = 0;
  1994. } else if (msgId == _bindMsgId) {
  1995. _bindMsgId = 0;
  1996. }
  1997. }
  1998. void SessionPrivate::resend(mtpMsgId msgId, crl::time msCanWait) {
  1999. const auto guard = gsl::finally([&] {
  2000. clearSpecialMsgId(msgId);
  2001. if (msCanWait >= 0) {
  2002. _sessionData->queueSendAnything(msCanWait);
  2003. }
  2004. });
  2005. if (const auto i = _sentContainers.find(msgId); i != end(_sentContainers)) {
  2006. DEBUG_LOG(("Message Info: resending container, msgId %1").arg(msgId));
  2007. const auto ids = std::move(i->second.messages);
  2008. _sentContainers.erase(i);
  2009. for (const auto innerMsgId : ids) {
  2010. resend(innerMsgId, -1);
  2011. }
  2012. return;
  2013. }
  2014. auto lock = QWriteLocker(_sessionData->haveSentMutex());
  2015. auto &haveSent = _sessionData->haveSentMap();
  2016. auto i = haveSent.find(msgId);
  2017. if (i == haveSent.end()) {
  2018. return;
  2019. }
  2020. auto request = i->second;
  2021. haveSent.erase(i);
  2022. lock.unlock();
  2023. request->lastSentTime = crl::now();
  2024. request->forceSendInContainer = true;
  2025. _resendingIds.emplace(msgId, request->requestId);
  2026. {
  2027. QWriteLocker locker(_sessionData->toSendMutex());
  2028. _sessionData->toSendMap().emplace(request->requestId, request);
  2029. }
  2030. }
  2031. void SessionPrivate::resendAll() {
  2032. auto lock = QWriteLocker(_sessionData->haveSentMutex());
  2033. auto haveSent = base::take(_sessionData->haveSentMap());
  2034. lock.unlock();
  2035. {
  2036. auto lock = QWriteLocker(_sessionData->toSendMutex());
  2037. auto &toSend = _sessionData->toSendMap();
  2038. const auto now = crl::now();
  2039. for (auto &[msgId, request] : haveSent) {
  2040. const auto requestId = request->requestId;
  2041. request->lastSentTime = now;
  2042. request->forceSendInContainer = true;
  2043. _resendingIds.emplace(msgId, requestId);
  2044. toSend.emplace(requestId, std::move(request));
  2045. }
  2046. }
  2047. _sessionData->queueSendAnything();
  2048. }
  2049. void SessionPrivate::onConnected(
  2050. not_null<AbstractConnection*> connection) {
  2051. disconnect(connection, &AbstractConnection::connected, nullptr, nullptr);
  2052. if (!connection->isConnected()) {
  2053. LOG(("Connection Error: not connected in onConnected(), "
  2054. "state: %1").arg(connection->debugState()));
  2055. return restart();
  2056. }
  2057. _waitForConnected = kMinConnectedTimeout;
  2058. _waitForConnectedTimer.cancel();
  2059. const auto i = ranges::find(
  2060. _testConnections,
  2061. connection.get(),
  2062. [](const TestConnection &test) { return test.data.get(); });
  2063. Assert(i != end(_testConnections));
  2064. const auto my = i->priority;
  2065. const auto j = ranges::find_if(
  2066. _testConnections,
  2067. [&](const TestConnection &test) { return test.priority > my; });
  2068. if (j != end(_testConnections)) {
  2069. DEBUG_LOG(("MTP Info: connection %1 succeed, waiting for %2.").arg(
  2070. i->data->tag(),
  2071. j->data->tag()));
  2072. _waitForBetterTimer.callOnce(kWaitForBetterTimeout);
  2073. } else {
  2074. DEBUG_LOG(("MTP Info: connection through IPv4 succeed."));
  2075. _waitForBetterTimer.cancel();
  2076. _connection = std::move(i->data);
  2077. _testConnections.clear();
  2078. checkAuthKey();
  2079. }
  2080. }
  2081. void SessionPrivate::onDisconnected(
  2082. not_null<AbstractConnection*> connection) {
  2083. removeTestConnection(connection);
  2084. if (_testConnections.empty()) {
  2085. destroyAllConnections();
  2086. restart();
  2087. } else {
  2088. confirmBestConnection();
  2089. }
  2090. }
  2091. void SessionPrivate::confirmBestConnection() {
  2092. if (_waitForBetterTimer.isActive()) {
  2093. return;
  2094. }
  2095. const auto i = ranges::max_element(
  2096. _testConnections,
  2097. std::less<>(),
  2098. [](const TestConnection &test) {
  2099. return test.data->isConnected() ? test.priority : -1;
  2100. });
  2101. Assert(i != end(_testConnections));
  2102. if (!i->data->isConnected()) {
  2103. return;
  2104. }
  2105. DEBUG_LOG(("MTP Info: can't connect through better, using %1."
  2106. ).arg(i->data->tag()));
  2107. _connection = std::move(i->data);
  2108. _testConnections.clear();
  2109. checkAuthKey();
  2110. }
  2111. void SessionPrivate::removeTestConnection(
  2112. not_null<AbstractConnection*> connection) {
  2113. _testConnections.erase(
  2114. ranges::remove(
  2115. _testConnections,
  2116. connection.get(),
  2117. [](const TestConnection &test) { return test.data.get(); }),
  2118. end(_testConnections));
  2119. }
  2120. void SessionPrivate::checkAuthKey() {
  2121. if (_keyId) {
  2122. authKeyChecked();
  2123. } else if (_instance->isKeysDestroyer()) {
  2124. applyAuthKey(_sessionData->getPersistentKey());
  2125. } else {
  2126. applyAuthKey(_sessionData->getTemporaryKey(
  2127. TemporaryKeyTypeByDcType(_currentDcType)));
  2128. }
  2129. }
  2130. void SessionPrivate::updateAuthKey() {
  2131. if (_instance->isKeysDestroyer() || _keyCreator || !_connection) {
  2132. return;
  2133. }
  2134. DEBUG_LOG(("AuthKey Info: Connection updating key from Session, dc %1"
  2135. ).arg(_shiftedDcId));
  2136. applyAuthKey(_sessionData->getTemporaryKey(
  2137. TemporaryKeyTypeByDcType(_currentDcType)));
  2138. }
  2139. void SessionPrivate::setCurrentKeyId(uint64 newKeyId) {
  2140. if (_keyId == newKeyId) {
  2141. return;
  2142. }
  2143. _keyId = newKeyId;
  2144. DEBUG_LOG(("MTP Info: auth key id set to id %1").arg(newKeyId));
  2145. changeSessionId();
  2146. }
  2147. void SessionPrivate::applyAuthKey(AuthKeyPtr &&encryptionKey) {
  2148. _encryptionKey = std::move(encryptionKey);
  2149. const auto newKeyId = _encryptionKey ? _encryptionKey->keyId() : 0;
  2150. if (_keyId) {
  2151. if (_keyId == newKeyId) {
  2152. return;
  2153. }
  2154. setCurrentKeyId(0);
  2155. DEBUG_LOG(("MTP Info: auth_key id for dc %1 changed, restarting..."
  2156. ).arg(_shiftedDcId));
  2157. if (_connection) {
  2158. restart();
  2159. }
  2160. return;
  2161. }
  2162. if (!_connection) {
  2163. return;
  2164. }
  2165. setCurrentKeyId(newKeyId);
  2166. Assert(!_connection->sentEncryptedWithKeyId());
  2167. DEBUG_LOG(("AuthKey Info: Connection update key from Session, "
  2168. "dc %1 result: %2"
  2169. ).arg(_shiftedDcId
  2170. ).arg(Logs::mb(&_keyId, sizeof(_keyId)).str()));
  2171. if (_keyId) {
  2172. return authKeyChecked();
  2173. }
  2174. if (_instance->isKeysDestroyer()) {
  2175. // We are here to destroy an old key, so we're done.
  2176. LOG(("MTP Error: No key %1 in updateAuthKey() for destroying."
  2177. ).arg(_shiftedDcId));
  2178. _instance->keyWasPossiblyDestroyed(_shiftedDcId);
  2179. } else if (noMediaKeyWithExistingRegularKey()) {
  2180. DEBUG_LOG(("AuthKey Info: No key in updateAuthKey() for media, "
  2181. "but someone has created regular, trying to acquire."));
  2182. const auto dcType = tryAcquireKeyCreation();
  2183. if (_keyCreator && dcType != _currentDcType) {
  2184. DEBUG_LOG(("AuthKey Info: "
  2185. "Dc type changed for creation, restarting."));
  2186. restart();
  2187. return;
  2188. }
  2189. }
  2190. if (_keyCreator) {
  2191. DEBUG_LOG(("AuthKey Info: No key in updateAuthKey(), creating."));
  2192. _keyCreator->start(
  2193. BareDcId(_shiftedDcId),
  2194. getProtocolDcId(),
  2195. _connection.get(),
  2196. &_instance->dcOptions());
  2197. } else {
  2198. DEBUG_LOG(("AuthKey Info: No key in updateAuthKey(), "
  2199. "but someone is creating already, waiting."));
  2200. }
  2201. }
  2202. bool SessionPrivate::noMediaKeyWithExistingRegularKey() const {
  2203. return (TemporaryKeyTypeByDcType(_currentDcType)
  2204. == TemporaryKeyType::MediaCluster)
  2205. && _sessionData->getTemporaryKey(TemporaryKeyType::Regular);
  2206. }
  2207. bool SessionPrivate::destroyOldEnoughPersistentKey() {
  2208. Expects(_keyCreator != nullptr);
  2209. const auto key = _keyCreator->bindPersistentKey();
  2210. Assert(key != nullptr);
  2211. const auto created = key->creationTime();
  2212. if (created > 0 && crl::now() - created < kKeyOldEnoughForDestroy) {
  2213. return false;
  2214. }
  2215. const auto instance = _instance;
  2216. const auto shiftedDcId = _shiftedDcId;
  2217. const auto keyId = key->keyId();
  2218. InvokeQueued(instance, [=] {
  2219. instance->keyDestroyedOnServer(shiftedDcId, keyId);
  2220. });
  2221. return true;
  2222. }
  2223. DcType SessionPrivate::tryAcquireKeyCreation() {
  2224. if (_keyCreator) {
  2225. return _currentDcType;
  2226. } else if (_instance->isKeysDestroyer()) {
  2227. return _realDcType;
  2228. }
  2229. const auto acquired = _sessionData->acquireKeyCreation(_realDcType);
  2230. if (acquired == CreatingKeyType::None) {
  2231. return _realDcType;
  2232. }
  2233. using Result = DcKeyResult;
  2234. using Error = DcKeyError;
  2235. auto delegate = BoundKeyCreator::Delegate();
  2236. delegate.unboundReady = [=](base::expected<Result, Error> result) {
  2237. if (!result) {
  2238. releaseKeyCreationOnFail();
  2239. if (result.error() == Error::UnknownPublicKey) {
  2240. if (_realDcType == DcType::Cdn) {
  2241. LOG(("Warning: CDN public RSA key not found"));
  2242. requestCDNConfig();
  2243. return;
  2244. }
  2245. LOG(("AuthKey Error: could not choose public RSA key"));
  2246. }
  2247. restart();
  2248. return;
  2249. }
  2250. DEBUG_LOG(("AuthKey Info: unbound key creation succeed, "
  2251. "ids: (%1, %2) server salts: (%3, %4)"
  2252. ).arg(result->temporaryKey
  2253. ? result->temporaryKey->keyId()
  2254. : 0
  2255. ).arg(result->persistentKey
  2256. ? result->persistentKey->keyId()
  2257. : 0
  2258. ).arg(result->temporaryServerSalt
  2259. ).arg(result->persistentServerSalt));
  2260. _sessionSalt = result->temporaryServerSalt;
  2261. result->temporaryKey->setExpiresAt(base::unixtime::now()
  2262. + kTemporaryExpiresIn
  2263. + kBindKeyAdditionalExpiresTimeout);
  2264. if (_realDcType != DcType::Cdn) {
  2265. auto key = result->persistentKey
  2266. ? std::move(result->persistentKey)
  2267. : _sessionData->getPersistentKey();
  2268. if (!key) {
  2269. releaseKeyCreationOnFail();
  2270. restart();
  2271. return;
  2272. }
  2273. _keyCreator->bind(std::move(key));
  2274. }
  2275. applyAuthKey(std::move(result->temporaryKey));
  2276. if (_realDcType == DcType::Cdn) {
  2277. _keyCreator = nullptr;
  2278. if (!_sessionData->releaseCdnKeyCreationOnDone(_encryptionKey)) {
  2279. restart();
  2280. } else {
  2281. _sessionData->queueNeedToResumeAndSend();
  2282. }
  2283. }
  2284. };
  2285. delegate.sentSome = [=](uint64 size) {
  2286. onSentSome(size);
  2287. };
  2288. delegate.receivedSome = [=] {
  2289. onReceivedSome();
  2290. };
  2291. auto request = DcKeyRequest();
  2292. request.persistentNeeded = (acquired == CreatingKeyType::Persistent);
  2293. request.temporaryExpiresIn = kTemporaryExpiresIn;
  2294. _keyCreator = std::make_unique<BoundKeyCreator>(
  2295. request,
  2296. std::move(delegate));
  2297. const auto forceUseRegular = (_realDcType == DcType::MediaCluster)
  2298. && (acquired != CreatingKeyType::TemporaryMediaCluster);
  2299. return forceUseRegular ? DcType::Regular : _realDcType;
  2300. }
  2301. void SessionPrivate::authKeyChecked() {
  2302. connect(_connection, &AbstractConnection::receivedData, [=] {
  2303. handleReceived();
  2304. });
  2305. if (_sessionSalt && setState(ConnectedState)) {
  2306. resendAll();
  2307. } // else receive salt in bad_server_salt first, then try to send all the requests
  2308. _pingIdToSend = base::RandomValue<uint64>(); // get server_salt
  2309. _sessionData->queueNeedToResumeAndSend();
  2310. }
  2311. void SessionPrivate::onError(
  2312. not_null<AbstractConnection*> connection,
  2313. qint32 errorCode) {
  2314. if (errorCode == -429) {
  2315. LOG(("Protocol Error: -429 flood code returned!"));
  2316. } else if (errorCode == -444) {
  2317. LOG(("Protocol Error: -444 bad dc_id code returned!"));
  2318. InvokeQueued(_instance, [instance = _instance] {
  2319. instance->badConfigurationError();
  2320. });
  2321. }
  2322. removeTestConnection(connection);
  2323. if (_testConnections.empty()) {
  2324. handleError(errorCode);
  2325. } else {
  2326. confirmBestConnection();
  2327. }
  2328. }
  2329. void SessionPrivate::handleError(int errorCode) {
  2330. destroyAllConnections();
  2331. _waitForConnectedTimer.cancel();
  2332. if (errorCode == -404) {
  2333. destroyTemporaryKey();
  2334. } else {
  2335. MTP_LOG(_shiftedDcId, ("Restarting after error in connection, error code: %1...").arg(errorCode));
  2336. return restart();
  2337. }
  2338. }
  2339. void SessionPrivate::destroyTemporaryKey() {
  2340. if (_instance->isKeysDestroyer()) {
  2341. LOG(("MTP Info: -404 error received in destroyer %1, assuming key was destroyed.").arg(_shiftedDcId));
  2342. _instance->keyWasPossiblyDestroyed(_shiftedDcId);
  2343. return;
  2344. }
  2345. LOG(("MTP Info: -404 error received in %1 with temporary key, assuming it was destroyed.").arg(_shiftedDcId));
  2346. releaseKeyCreationOnFail();
  2347. if (_encryptionKey) {
  2348. _sessionData->destroyTemporaryKey(_encryptionKey->keyId());
  2349. }
  2350. applyAuthKey(nullptr);
  2351. restart();
  2352. }
  2353. bool SessionPrivate::sendSecureRequest(
  2354. SerializedRequest &&request,
  2355. bool needAnyResponse) {
  2356. request.addPadding(false);
  2357. uint32 fullSize = request->size();
  2358. if (fullSize < 9) {
  2359. return false;
  2360. }
  2361. auto messageSize = request.messageSize();
  2362. if (messageSize < 5 || fullSize < messageSize + 4) {
  2363. return false;
  2364. }
  2365. memcpy(request->data() + 0, &_sessionSalt, 2 * sizeof(mtpPrime));
  2366. memcpy(request->data() + 2, &_sessionId, 2 * sizeof(mtpPrime));
  2367. auto from = request->constData() + 4;
  2368. MTP_LOG(_shiftedDcId, ("Send: ")
  2369. + DumpToText(from, from + messageSize)
  2370. + QString(" (dc:%1,key:%2)"
  2371. ).arg(AbstractConnection::ProtocolDcDebugId(getProtocolDcId())
  2372. ).arg(_encryptionKey->keyId()));
  2373. uchar encryptedSHA256[32];
  2374. MTPint128 &msgKey(*(MTPint128*)(encryptedSHA256 + 8));
  2375. SHA256_CTX msgKeyLargeContext;
  2376. SHA256_Init(&msgKeyLargeContext);
  2377. SHA256_Update(&msgKeyLargeContext, _encryptionKey->partForMsgKey(true), 32);
  2378. SHA256_Update(&msgKeyLargeContext, request->constData(), fullSize * sizeof(mtpPrime));
  2379. SHA256_Final(encryptedSHA256, &msgKeyLargeContext);
  2380. auto packet = _connection->prepareSecurePacket(_keyId, msgKey, fullSize);
  2381. const auto prefix = packet.size();
  2382. packet.resize(prefix + fullSize);
  2383. aesIgeEncrypt(
  2384. request->constData(),
  2385. &packet[prefix],
  2386. fullSize * sizeof(mtpPrime),
  2387. _encryptionKey,
  2388. msgKey);
  2389. DEBUG_LOG(("MTP Info: sending request, size: %1, num: %2, time: %3").arg(fullSize + 6).arg((*request)[4]).arg((*request)[5]));
  2390. _connection->setSentEncryptedWithKeyId(_keyId);
  2391. _connection->sendData(std::move(packet));
  2392. if (needAnyResponse) {
  2393. onSentSome((prefix + fullSize) * sizeof(mtpPrime));
  2394. }
  2395. return true;
  2396. }
  2397. mtpRequestId SessionPrivate::wasSent(mtpMsgId msgId) const {
  2398. if (msgId == _pingMsgId || msgId == _bindMsgId) {
  2399. return mtpRequestId(0xFFFFFFFF);
  2400. }
  2401. if (const auto i = _resendingIds.find(msgId); i != end(_resendingIds)) {
  2402. return i->second;
  2403. }
  2404. if (const auto i = _ackedIds.find(msgId); i != end(_ackedIds)) {
  2405. return i->second;
  2406. }
  2407. if (const auto i = _sentContainers.find(msgId); i != end(_sentContainers)) {
  2408. return mtpRequestId(0xFFFFFFFF);
  2409. }
  2410. {
  2411. QReadLocker locker(_sessionData->haveSentMutex());
  2412. const auto &haveSent = _sessionData->haveSentMap();
  2413. const auto i = haveSent.find(msgId);
  2414. if (i != haveSent.end()) {
  2415. return i->second->requestId
  2416. ? i->second->requestId
  2417. : mtpRequestId(0xFFFFFFFF);
  2418. }
  2419. }
  2420. return 0;
  2421. }
  2422. void SessionPrivate::clearUnboundKeyCreator() {
  2423. if (_keyCreator) {
  2424. _keyCreator->stop();
  2425. }
  2426. }
  2427. void SessionPrivate::releaseKeyCreationOnFail() {
  2428. if (!_keyCreator) {
  2429. return;
  2430. }
  2431. _keyCreator = nullptr;
  2432. _sessionData->releaseKeyCreationOnFail();
  2433. }
  2434. } // namespace details
  2435. } // namespace MTP