session_private.h 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246
  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. #pragma once
  8. #include "mtproto/details/mtproto_received_ids_manager.h"
  9. #include "mtproto/details/mtproto_serialized_request.h"
  10. #include "mtproto/mtproto_auth_key.h"
  11. #include "mtproto/mtproto_dc_options.h"
  12. #include "mtproto/connection_abstract.h"
  13. #include "mtproto/facade.h"
  14. #include "base/timer.h"
  15. namespace MTP {
  16. namespace details {
  17. class BoundKeyCreator;
  18. } // namespace details
  19. class Instance;
  20. namespace details {
  21. class AbstractConnection;
  22. class SessionData;
  23. class RSAPublicKey;
  24. struct SessionOptions;
  25. class SessionPrivate final : public QObject {
  26. public:
  27. SessionPrivate(
  28. not_null<Instance*> instance,
  29. not_null<QThread*> thread,
  30. std::shared_ptr<SessionData> data,
  31. ShiftedDcId shiftedDcId);
  32. ~SessionPrivate();
  33. [[nodiscard]] int32 getShiftedDcId() const;
  34. void dcOptionsChanged();
  35. void cdnConfigChanged();
  36. [[nodiscard]] int32 getState() const;
  37. [[nodiscard]] QString transport() const;
  38. void updateAuthKey();
  39. void restartNow();
  40. void sendPingForce();
  41. void tryToSend();
  42. private:
  43. static constexpr auto kUpdateStateAlways = 666;
  44. struct TestConnection {
  45. ConnectionPointer data;
  46. int priority = 0;
  47. };
  48. struct SentContainer {
  49. crl::time sent = 0;
  50. std::vector<mtpMsgId> messages;
  51. };
  52. enum class HandleResult {
  53. Success,
  54. Ignored,
  55. RestartConnection,
  56. ResetSession,
  57. DestroyTemporaryKey,
  58. ParseError,
  59. };
  60. void connectToServer(bool afterConfig = false);
  61. void connectingTimedOut();
  62. void doDisconnect();
  63. void restart();
  64. void requestCDNConfig();
  65. void handleError(int errorCode);
  66. void onError(
  67. not_null<AbstractConnection*> connection,
  68. qint32 errorCode);
  69. void onConnected(not_null<AbstractConnection*> connection);
  70. void onDisconnected(not_null<AbstractConnection*> connection);
  71. void onSentSome(uint64 size);
  72. void onReceivedSome();
  73. void handleReceived();
  74. void retryByTimer();
  75. void waitConnectedFailed();
  76. void waitReceivedFailed();
  77. void waitBetterFailed();
  78. void markConnectionOld();
  79. void sendPingByTimer();
  80. void destroyAllConnections();
  81. void confirmBestConnection();
  82. void removeTestConnection(not_null<AbstractConnection*> connection);
  83. [[nodiscard]] int16 getProtocolDcId() const;
  84. void checkSentRequests();
  85. void clearOldContainers();
  86. mtpMsgId placeToContainer(
  87. SerializedRequest &toSendRequest,
  88. mtpMsgId &bigMsgId,
  89. bool forceNewMsgId,
  90. SerializedRequest &req);
  91. mtpMsgId prepareToSend(
  92. SerializedRequest &request,
  93. mtpMsgId currentLastId,
  94. bool forceNewMsgId);
  95. mtpMsgId replaceMsgId(
  96. SerializedRequest &request,
  97. mtpMsgId newId);
  98. bool sendSecureRequest(
  99. SerializedRequest &&request,
  100. bool needAnyResponse);
  101. mtpRequestId wasSent(mtpMsgId msgId) const;
  102. struct OuterInfo {
  103. mtpMsgId outerMsgId = 0;
  104. uint64 serverSalt = 0;
  105. int32 serverTime = 0;
  106. bool badTime = false;
  107. };
  108. [[nodiscard]] HandleResult handleOneReceived(
  109. const mtpPrime *from,
  110. const mtpPrime *end,
  111. uint64 msgId,
  112. OuterInfo info);
  113. [[nodiscard]] HandleResult handleBindResponse(
  114. mtpMsgId requestMsgId,
  115. const mtpBuffer &response);
  116. mtpBuffer ungzip(const mtpPrime *from, const mtpPrime *end) const;
  117. void handleMsgsStates(const QVector<MTPlong> &ids, const QByteArray &states);
  118. // _sessionDataMutex must be locked for read.
  119. bool setState(int state, int ifState = kUpdateStateAlways);
  120. void appendTestConnection(
  121. DcOptions::Variants::Protocol protocol,
  122. const QString &ip,
  123. int port,
  124. const bytes::vector &protocolSecret);
  125. // if badTime received - search for ids in sessionData->haveSent and sessionData->wereAcked and sync time/salt, return true if found
  126. bool requestsFixTimeSalt(const QVector<MTPlong> &ids, const OuterInfo &info);
  127. // if we had a confirmed fast request use its unixtime as a correct one.
  128. void correctUnixtimeByFastRequest(
  129. const QVector<MTPlong> &ids,
  130. TimeId serverTime);
  131. void correctUnixtimeWithBadLocal(TimeId serverTime);
  132. // remove msgs with such ids from sessionData->haveSent, add to sessionData->wereAcked
  133. void requestsAcked(const QVector<MTPlong> &ids, bool byResponse = false);
  134. void resend(mtpMsgId msgId, crl::time msCanWait = 0);
  135. void resendAll();
  136. void clearSpecialMsgId(mtpMsgId msgId);
  137. [[nodiscard]] DcType tryAcquireKeyCreation();
  138. void resetSession();
  139. void checkAuthKey();
  140. void authKeyChecked();
  141. void destroyTemporaryKey();
  142. void clearUnboundKeyCreator();
  143. void releaseKeyCreationOnFail();
  144. void applyAuthKey(AuthKeyPtr &&encryptionKey);
  145. [[nodiscard]] bool noMediaKeyWithExistingRegularKey() const;
  146. bool destroyOldEnoughPersistentKey();
  147. void setCurrentKeyId(uint64 newKeyId);
  148. void changeSessionId();
  149. [[nodiscard]] bool markSessionAsStarted();
  150. [[nodiscard]] uint32 nextRequestSeqNumber(bool needAck);
  151. [[nodiscard]] bool realDcTypeChanged();
  152. [[nodiscard]] MTPVector<MTPJSONObjectValue> prepareInitParams();
  153. const not_null<Instance*> _instance;
  154. const ShiftedDcId _shiftedDcId = 0;
  155. DcType _realDcType = DcType();
  156. DcType _currentDcType = DcType();
  157. mutable QReadWriteLock _stateMutex;
  158. int _state = DisconnectedState;
  159. bool _needSessionReset = false;
  160. ConnectionPointer _connection;
  161. std::vector<TestConnection> _testConnections;
  162. crl::time _startedConnectingAt = 0;
  163. base::Timer _retryTimer; // exp retry timer
  164. int _retryTimeout = 1;
  165. qint64 _retryWillFinish = 0;
  166. base::Timer _oldConnectionTimer;
  167. bool _oldConnection = true;
  168. base::Timer _waitForConnectedTimer;
  169. base::Timer _waitForReceivedTimer;
  170. base::Timer _waitForBetterTimer;
  171. crl::time _waitForReceived = 0;
  172. crl::time _waitForConnected = 0;
  173. crl::time _firstSentAt = -1;
  174. mtpPingId _pingId = 0;
  175. mtpPingId _pingIdToSend = 0;
  176. crl::time _pingSendAt = 0;
  177. mtpMsgId _pingMsgId = 0;
  178. base::Timer _pingSender;
  179. base::Timer _checkSentRequestsTimer;
  180. base::Timer _clearOldContainersTimer;
  181. std::shared_ptr<SessionData> _sessionData;
  182. std::unique_ptr<SessionOptions> _options;
  183. AuthKeyPtr _encryptionKey;
  184. uint64 _keyId = 0;
  185. uint64 _sessionId = 0;
  186. uint64 _sessionSalt = 0;
  187. uint32 _messagesCounter = 0;
  188. bool _sessionMarkedAsStarted = false;
  189. QVector<MTPlong> _ackRequestData;
  190. QVector<MTPlong> _resendRequestData;
  191. base::flat_set<mtpMsgId> _stateRequestData;
  192. ReceivedIdsManager _receivedMessageIds;
  193. base::flat_map<mtpMsgId, mtpRequestId> _resendingIds;
  194. base::flat_map<mtpMsgId, mtpRequestId> _ackedIds;
  195. base::flat_map<mtpMsgId, SerializedRequest> _stateAndResendRequests;
  196. base::flat_map<mtpMsgId, SentContainer> _sentContainers;
  197. std::unique_ptr<BoundKeyCreator> _keyCreator;
  198. mtpMsgId _bindMsgId = 0;
  199. crl::time _bindMessageSent = 0;
  200. };
  201. extern const char kOptionPreferIPv6[];
  202. } // namespace details
  203. } // namespace MTP