session.h 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222
  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 "base/timer.h"
  9. #include "mtproto/mtproto_response.h"
  10. #include "mtproto/mtproto_proxy_data.h"
  11. #include "mtproto/details/mtproto_serialized_request.h"
  12. #include <QtCore/QTimer>
  13. namespace MTP {
  14. class Instance;
  15. class AuthKey;
  16. using AuthKeyPtr = std::shared_ptr<AuthKey>;
  17. enum class DcType;
  18. namespace details {
  19. class Dcenter;
  20. class SessionPrivate;
  21. enum class TemporaryKeyType;
  22. enum class CreatingKeyType;
  23. struct SessionOptions {
  24. SessionOptions() = default;
  25. SessionOptions(
  26. const QString &systemLangCode,
  27. const QString &cloudLangCode,
  28. const QString &langPackName,
  29. const ProxyData &proxy,
  30. bool useIPv4,
  31. bool useIPv6,
  32. bool useHttp,
  33. bool useTcp);
  34. QString systemLangCode;
  35. QString cloudLangCode;
  36. QString langPackName;
  37. ProxyData proxy;
  38. bool useIPv4 = true;
  39. bool useIPv6 = true;
  40. bool useHttp = true;
  41. bool useTcp = true;
  42. };
  43. class Session;
  44. class SessionData final {
  45. public:
  46. explicit SessionData(not_null<Session*> creator) : _owner(creator) {
  47. }
  48. void notifyConnectionInited(const SessionOptions &options);
  49. void setOptions(SessionOptions options) {
  50. QWriteLocker locker(&_optionsLock);
  51. _options = options;
  52. }
  53. [[nodiscard]] SessionOptions options() const {
  54. QReadLocker locker(&_optionsLock);
  55. return _options;
  56. }
  57. not_null<QReadWriteLock*> toSendMutex() {
  58. return &_toSendLock;
  59. }
  60. not_null<QReadWriteLock*> haveSentMutex() {
  61. return &_haveSentLock;
  62. }
  63. not_null<QReadWriteLock*> haveReceivedMutex() {
  64. return &_haveReceivedLock;
  65. }
  66. base::flat_map<mtpRequestId, SerializedRequest> &toSendMap() {
  67. return _toSend;
  68. }
  69. base::flat_map<mtpMsgId, SerializedRequest> &haveSentMap() {
  70. return _haveSent;
  71. }
  72. std::vector<Response> &haveReceivedMessages() {
  73. return _receivedMessages;
  74. }
  75. // SessionPrivate -> Session interface.
  76. void queueTryToReceive();
  77. void queueNeedToResumeAndSend();
  78. void queueConnectionStateChange(int newState);
  79. void queueResetDone();
  80. void queueSendAnything(crl::time msCanWait = 0);
  81. [[nodiscard]] bool connectionInited() const;
  82. [[nodiscard]] AuthKeyPtr getPersistentKey() const;
  83. [[nodiscard]] AuthKeyPtr getTemporaryKey(TemporaryKeyType type) const;
  84. [[nodiscard]] CreatingKeyType acquireKeyCreation(DcType type);
  85. [[nodiscard]] bool releaseKeyCreationOnDone(
  86. const AuthKeyPtr &temporaryKey,
  87. const AuthKeyPtr &persistentKeyUsedForBind);
  88. [[nodiscard]] bool releaseCdnKeyCreationOnDone(
  89. const AuthKeyPtr &temporaryKey);
  90. void releaseKeyCreationOnFail();
  91. void destroyTemporaryKey(uint64 keyId);
  92. void detach();
  93. private:
  94. template <typename Callback>
  95. void withSession(Callback &&callback);
  96. Session *_owner = nullptr;
  97. mutable QMutex _ownerMutex;
  98. SessionOptions _options;
  99. mutable QReadWriteLock _optionsLock;
  100. base::flat_map<mtpRequestId, SerializedRequest> _toSend; // map of request_id -> request, that is waiting to be sent
  101. QReadWriteLock _toSendLock;
  102. base::flat_map<mtpMsgId, SerializedRequest> _haveSent; // map of msg_id -> request, that was sent
  103. QReadWriteLock _haveSentLock;
  104. std::vector<Response> _receivedMessages; // list of responses / updates that should be processed in the main thread
  105. QReadWriteLock _haveReceivedLock;
  106. };
  107. class Session final : public QObject {
  108. public:
  109. // Main thread.
  110. Session(
  111. not_null<Instance*> instance,
  112. not_null<QThread*> thread,
  113. ShiftedDcId shiftedDcId,
  114. not_null<Dcenter*> dc);
  115. ~Session();
  116. void start();
  117. void reInitConnection();
  118. void setConnectionNotInited();
  119. void restart();
  120. void refreshOptions();
  121. void stop();
  122. void kill();
  123. void unpaused();
  124. // Thread-safe.
  125. [[nodiscard]] ShiftedDcId getDcWithShift() const;
  126. [[nodiscard]] AuthKeyPtr getPersistentKey() const;
  127. [[nodiscard]] AuthKeyPtr getTemporaryKey(TemporaryKeyType type) const;
  128. [[nodiscard]] bool connectionInited() const;
  129. void sendPrepared(
  130. const SerializedRequest &request,
  131. crl::time msCanWait = 0);
  132. // SessionPrivate thread.
  133. [[nodiscard]] CreatingKeyType acquireKeyCreation(DcType type);
  134. [[nodiscard]] bool releaseKeyCreationOnDone(
  135. const AuthKeyPtr &temporaryKey,
  136. const AuthKeyPtr &persistentKeyUsedForBind);
  137. [[nodiscard]] bool releaseCdnKeyCreationOnDone(const AuthKeyPtr &temporaryKey);
  138. void releaseKeyCreationOnFail();
  139. void destroyTemporaryKey(uint64 keyId);
  140. void notifyDcConnectionInited();
  141. void ping();
  142. void cancel(mtpRequestId requestId, mtpMsgId msgId);
  143. int requestState(mtpRequestId requestId) const;
  144. int getState() const;
  145. QString transport() const;
  146. void tryToReceive();
  147. void needToResumeAndSend();
  148. void connectionStateChange(int newState);
  149. void resetDone();
  150. void sendAnything(crl::time msCanWait = 0);
  151. private:
  152. void watchDcKeyChanges();
  153. void watchDcOptionsChanges();
  154. void killConnection();
  155. [[nodiscard]] bool releaseGenericKeyCreationOnDone(
  156. const AuthKeyPtr &temporaryKey,
  157. const AuthKeyPtr &persistentKeyUsedForBind);
  158. const not_null<Instance*> _instance;
  159. const ShiftedDcId _shiftedDcId = 0;
  160. const not_null<Dcenter*> _dc;
  161. const std::shared_ptr<SessionData> _data;
  162. const not_null<QThread*> _thread;
  163. SessionPrivate *_private = nullptr;
  164. bool _killed = false;
  165. bool _needToReceive = false;
  166. AuthKeyPtr _dcKeyForCheck;
  167. CreatingKeyType _myKeyCreation = CreatingKeyType();
  168. crl::time _msSendCall = 0;
  169. crl::time _msWait = 0;
  170. bool _ping = false;
  171. base::Timer _sender;
  172. rpl::lifetime _lifetime;
  173. };
  174. } // namespace details
  175. } // namespace MTP