| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246 |
- /*
- This file is part of Telegram Desktop,
- the official desktop application for the Telegram messaging service.
- For license and copyright information please follow this link:
- https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
- */
- #pragma once
- #include "mtproto/details/mtproto_received_ids_manager.h"
- #include "mtproto/details/mtproto_serialized_request.h"
- #include "mtproto/mtproto_auth_key.h"
- #include "mtproto/mtproto_dc_options.h"
- #include "mtproto/connection_abstract.h"
- #include "mtproto/facade.h"
- #include "base/timer.h"
- namespace MTP {
- namespace details {
- class BoundKeyCreator;
- } // namespace details
- class Instance;
- namespace details {
- class AbstractConnection;
- class SessionData;
- class RSAPublicKey;
- struct SessionOptions;
- class SessionPrivate final : public QObject {
- public:
- SessionPrivate(
- not_null<Instance*> instance,
- not_null<QThread*> thread,
- std::shared_ptr<SessionData> data,
- ShiftedDcId shiftedDcId);
- ~SessionPrivate();
- [[nodiscard]] int32 getShiftedDcId() const;
- void dcOptionsChanged();
- void cdnConfigChanged();
- [[nodiscard]] int32 getState() const;
- [[nodiscard]] QString transport() const;
- void updateAuthKey();
- void restartNow();
- void sendPingForce();
- void tryToSend();
- private:
- static constexpr auto kUpdateStateAlways = 666;
- struct TestConnection {
- ConnectionPointer data;
- int priority = 0;
- };
- struct SentContainer {
- crl::time sent = 0;
- std::vector<mtpMsgId> messages;
- };
- enum class HandleResult {
- Success,
- Ignored,
- RestartConnection,
- ResetSession,
- DestroyTemporaryKey,
- ParseError,
- };
- void connectToServer(bool afterConfig = false);
- void connectingTimedOut();
- void doDisconnect();
- void restart();
- void requestCDNConfig();
- void handleError(int errorCode);
- void onError(
- not_null<AbstractConnection*> connection,
- qint32 errorCode);
- void onConnected(not_null<AbstractConnection*> connection);
- void onDisconnected(not_null<AbstractConnection*> connection);
- void onSentSome(uint64 size);
- void onReceivedSome();
- void handleReceived();
- void retryByTimer();
- void waitConnectedFailed();
- void waitReceivedFailed();
- void waitBetterFailed();
- void markConnectionOld();
- void sendPingByTimer();
- void destroyAllConnections();
- void confirmBestConnection();
- void removeTestConnection(not_null<AbstractConnection*> connection);
- [[nodiscard]] int16 getProtocolDcId() const;
- void checkSentRequests();
- void clearOldContainers();
- mtpMsgId placeToContainer(
- SerializedRequest &toSendRequest,
- mtpMsgId &bigMsgId,
- bool forceNewMsgId,
- SerializedRequest &req);
- mtpMsgId prepareToSend(
- SerializedRequest &request,
- mtpMsgId currentLastId,
- bool forceNewMsgId);
- mtpMsgId replaceMsgId(
- SerializedRequest &request,
- mtpMsgId newId);
- bool sendSecureRequest(
- SerializedRequest &&request,
- bool needAnyResponse);
- mtpRequestId wasSent(mtpMsgId msgId) const;
- struct OuterInfo {
- mtpMsgId outerMsgId = 0;
- uint64 serverSalt = 0;
- int32 serverTime = 0;
- bool badTime = false;
- };
- [[nodiscard]] HandleResult handleOneReceived(
- const mtpPrime *from,
- const mtpPrime *end,
- uint64 msgId,
- OuterInfo info);
- [[nodiscard]] HandleResult handleBindResponse(
- mtpMsgId requestMsgId,
- const mtpBuffer &response);
- mtpBuffer ungzip(const mtpPrime *from, const mtpPrime *end) const;
- void handleMsgsStates(const QVector<MTPlong> &ids, const QByteArray &states);
- // _sessionDataMutex must be locked for read.
- bool setState(int state, int ifState = kUpdateStateAlways);
- void appendTestConnection(
- DcOptions::Variants::Protocol protocol,
- const QString &ip,
- int port,
- const bytes::vector &protocolSecret);
- // if badTime received - search for ids in sessionData->haveSent and sessionData->wereAcked and sync time/salt, return true if found
- bool requestsFixTimeSalt(const QVector<MTPlong> &ids, const OuterInfo &info);
- // if we had a confirmed fast request use its unixtime as a correct one.
- void correctUnixtimeByFastRequest(
- const QVector<MTPlong> &ids,
- TimeId serverTime);
- void correctUnixtimeWithBadLocal(TimeId serverTime);
- // remove msgs with such ids from sessionData->haveSent, add to sessionData->wereAcked
- void requestsAcked(const QVector<MTPlong> &ids, bool byResponse = false);
- void resend(mtpMsgId msgId, crl::time msCanWait = 0);
- void resendAll();
- void clearSpecialMsgId(mtpMsgId msgId);
- [[nodiscard]] DcType tryAcquireKeyCreation();
- void resetSession();
- void checkAuthKey();
- void authKeyChecked();
- void destroyTemporaryKey();
- void clearUnboundKeyCreator();
- void releaseKeyCreationOnFail();
- void applyAuthKey(AuthKeyPtr &&encryptionKey);
- [[nodiscard]] bool noMediaKeyWithExistingRegularKey() const;
- bool destroyOldEnoughPersistentKey();
- void setCurrentKeyId(uint64 newKeyId);
- void changeSessionId();
- [[nodiscard]] bool markSessionAsStarted();
- [[nodiscard]] uint32 nextRequestSeqNumber(bool needAck);
- [[nodiscard]] bool realDcTypeChanged();
- [[nodiscard]] MTPVector<MTPJSONObjectValue> prepareInitParams();
- const not_null<Instance*> _instance;
- const ShiftedDcId _shiftedDcId = 0;
- DcType _realDcType = DcType();
- DcType _currentDcType = DcType();
- mutable QReadWriteLock _stateMutex;
- int _state = DisconnectedState;
- bool _needSessionReset = false;
- ConnectionPointer _connection;
- std::vector<TestConnection> _testConnections;
- crl::time _startedConnectingAt = 0;
- base::Timer _retryTimer; // exp retry timer
- int _retryTimeout = 1;
- qint64 _retryWillFinish = 0;
- base::Timer _oldConnectionTimer;
- bool _oldConnection = true;
- base::Timer _waitForConnectedTimer;
- base::Timer _waitForReceivedTimer;
- base::Timer _waitForBetterTimer;
- crl::time _waitForReceived = 0;
- crl::time _waitForConnected = 0;
- crl::time _firstSentAt = -1;
- mtpPingId _pingId = 0;
- mtpPingId _pingIdToSend = 0;
- crl::time _pingSendAt = 0;
- mtpMsgId _pingMsgId = 0;
- base::Timer _pingSender;
- base::Timer _checkSentRequestsTimer;
- base::Timer _clearOldContainersTimer;
- std::shared_ptr<SessionData> _sessionData;
- std::unique_ptr<SessionOptions> _options;
- AuthKeyPtr _encryptionKey;
- uint64 _keyId = 0;
- uint64 _sessionId = 0;
- uint64 _sessionSalt = 0;
- uint32 _messagesCounter = 0;
- bool _sessionMarkedAsStarted = false;
- QVector<MTPlong> _ackRequestData;
- QVector<MTPlong> _resendRequestData;
- base::flat_set<mtpMsgId> _stateRequestData;
- ReceivedIdsManager _receivedMessageIds;
- base::flat_map<mtpMsgId, mtpRequestId> _resendingIds;
- base::flat_map<mtpMsgId, mtpRequestId> _ackedIds;
- base::flat_map<mtpMsgId, SerializedRequest> _stateAndResendRequests;
- base::flat_map<mtpMsgId, SentContainer> _sentContainers;
- std::unique_ptr<BoundKeyCreator> _keyCreator;
- mtpMsgId _bindMsgId = 0;
- crl::time _bindMessageSent = 0;
- };
- extern const char kOptionPreferIPv6[];
- } // namespace details
- } // namespace MTP
|