2014-05-30 08:53:19 +00:00
|
|
|
/*
|
|
|
|
This file is part of Telegram Desktop,
|
2018-01-03 10:23:14 +00:00
|
|
|
the official desktop application for the Telegram messaging service.
|
2014-05-30 08:53:19 +00:00
|
|
|
|
2018-01-03 10:23:14 +00:00
|
|
|
For license and copyright information please follow this link:
|
|
|
|
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
2014-05-30 08:53:19 +00:00
|
|
|
*/
|
|
|
|
#pragma once
|
|
|
|
|
2019-11-20 10:41:14 +00:00
|
|
|
#include "mtproto/details/mtproto_received_ids_manager.h"
|
2019-11-22 09:15:38 +00:00
|
|
|
#include "mtproto/details/mtproto_serialized_request.h"
|
2019-11-18 09:28:14 +00:00
|
|
|
#include "mtproto/mtproto_auth_key.h"
|
2020-06-17 09:36:25 +00:00
|
|
|
#include "mtproto/mtproto_dc_options.h"
|
2018-04-24 19:09:20 +00:00
|
|
|
#include "mtproto/connection_abstract.h"
|
2019-11-13 08:31:12 +00:00
|
|
|
#include "mtproto/facade.h"
|
2018-08-10 19:19:46 +00:00
|
|
|
#include "base/openssl_help.h"
|
2018-04-24 19:09:20 +00:00
|
|
|
#include "base/timer.h"
|
2014-05-30 08:53:19 +00:00
|
|
|
|
2016-03-24 08:57:11 +00:00
|
|
|
namespace MTP {
|
2019-11-13 14:12:04 +00:00
|
|
|
namespace details {
|
2019-11-20 09:16:53 +00:00
|
|
|
class BoundKeyCreator;
|
2019-11-13 14:12:04 +00:00
|
|
|
} // namespace details
|
2017-02-24 17:15:41 +00:00
|
|
|
|
|
|
|
class Instance;
|
|
|
|
|
2019-12-02 13:10:19 +00:00
|
|
|
namespace details {
|
2014-05-30 08:53:19 +00:00
|
|
|
|
2017-02-23 06:57:04 +00:00
|
|
|
class AbstractConnection;
|
2016-03-24 08:57:11 +00:00
|
|
|
class SessionData;
|
2017-03-09 18:13:55 +00:00
|
|
|
class RSAPublicKey;
|
2019-12-02 13:10:19 +00:00
|
|
|
struct SessionOptions;
|
2014-05-30 08:53:19 +00:00
|
|
|
|
2019-12-02 13:10:19 +00:00
|
|
|
class SessionPrivate final : public QObject {
|
2014-05-30 08:53:19 +00:00
|
|
|
public:
|
2019-12-02 13:10:19 +00:00
|
|
|
SessionPrivate(
|
2018-04-24 19:09:20 +00:00
|
|
|
not_null<Instance*> instance,
|
|
|
|
not_null<QThread*> thread,
|
2019-11-18 12:53:37 +00:00
|
|
|
std::shared_ptr<SessionData> data,
|
2018-04-24 19:09:20 +00:00
|
|
|
ShiftedDcId shiftedDcId);
|
2019-12-02 13:10:19 +00:00
|
|
|
~SessionPrivate();
|
2014-11-13 11:27:10 +00:00
|
|
|
|
2019-11-27 14:22:22 +00:00
|
|
|
[[nodiscard]] int32 getShiftedDcId() const;
|
2019-11-27 10:41:17 +00:00
|
|
|
void dcOptionsChanged();
|
2019-11-27 14:22:22 +00:00
|
|
|
void cdnConfigChanged();
|
2014-05-30 08:53:19 +00:00
|
|
|
|
2019-11-27 14:22:22 +00:00
|
|
|
[[nodiscard]] int32 getState() const;
|
|
|
|
[[nodiscard]] QString transport() const;
|
2014-05-30 08:53:19 +00:00
|
|
|
|
2019-11-27 14:22:22 +00:00
|
|
|
void updateAuthKey();
|
2014-05-30 08:53:19 +00:00
|
|
|
void restartNow();
|
2019-11-27 14:22:22 +00:00
|
|
|
void sendPingForce();
|
2014-05-30 08:53:19 +00:00
|
|
|
void tryToSend();
|
|
|
|
|
|
|
|
private:
|
2019-11-27 14:22:22 +00:00
|
|
|
static constexpr auto kUpdateStateAlways = 666;
|
|
|
|
|
2018-04-24 19:09:20 +00:00
|
|
|
struct TestConnection {
|
|
|
|
ConnectionPointer data;
|
|
|
|
int priority = 0;
|
|
|
|
};
|
2019-12-02 10:32:09 +00:00
|
|
|
struct SentContainer {
|
|
|
|
crl::time sent = 0;
|
|
|
|
std::vector<mtpMsgId> messages;
|
|
|
|
};
|
2019-11-18 12:53:37 +00:00
|
|
|
enum class HandleResult {
|
|
|
|
Success,
|
|
|
|
Ignored,
|
|
|
|
RestartConnection,
|
|
|
|
ResetSession,
|
2019-11-19 10:10:51 +00:00
|
|
|
DestroyTemporaryKey,
|
2019-11-18 12:53:37 +00:00
|
|
|
ParseError,
|
|
|
|
};
|
|
|
|
|
2017-03-23 16:11:35 +00:00
|
|
|
void connectToServer(bool afterConfig = false);
|
2019-07-10 15:03:48 +00:00
|
|
|
void connectingTimedOut();
|
2015-08-08 09:14:47 +00:00
|
|
|
void doDisconnect();
|
2017-02-25 16:44:02 +00:00
|
|
|
void restart();
|
2017-03-23 16:11:35 +00:00
|
|
|
void requestCDNConfig();
|
|
|
|
void handleError(int errorCode);
|
2018-04-24 19:09:20 +00:00
|
|
|
void onError(
|
|
|
|
not_null<AbstractConnection*> connection,
|
|
|
|
qint32 errorCode);
|
|
|
|
void onConnected(not_null<AbstractConnection*> connection);
|
|
|
|
void onDisconnected(not_null<AbstractConnection*> connection);
|
2019-11-15 13:04:32 +00:00
|
|
|
void onSentSome(uint64 size);
|
|
|
|
void onReceivedSome();
|
|
|
|
|
|
|
|
void handleReceived();
|
2018-04-24 19:09:20 +00:00
|
|
|
|
|
|
|
void retryByTimer();
|
|
|
|
void waitConnectedFailed();
|
|
|
|
void waitReceivedFailed();
|
|
|
|
void waitBetterFailed();
|
|
|
|
void markConnectionOld();
|
|
|
|
void sendPingByTimer();
|
2018-04-23 10:24:03 +00:00
|
|
|
void destroyAllConnections();
|
2019-11-15 13:04:32 +00:00
|
|
|
|
2018-04-24 19:09:20 +00:00
|
|
|
void confirmBestConnection();
|
|
|
|
void removeTestConnection(not_null<AbstractConnection*> connection);
|
2019-11-20 10:41:14 +00:00
|
|
|
[[nodiscard]] int16 getProtocolDcId() const;
|
|
|
|
|
|
|
|
void checkSentRequests();
|
2019-12-02 10:32:09 +00:00
|
|
|
void clearOldContainers();
|
2014-05-30 08:53:19 +00:00
|
|
|
|
2018-06-25 18:55:27 +00:00
|
|
|
mtpMsgId placeToContainer(
|
2019-12-02 13:10:19 +00:00
|
|
|
SerializedRequest &toSendRequest,
|
2018-06-25 18:55:27 +00:00
|
|
|
mtpMsgId &bigMsgId,
|
2019-11-19 16:14:50 +00:00
|
|
|
bool forceNewMsgId,
|
2019-12-02 13:10:19 +00:00
|
|
|
SerializedRequest &req);
|
2019-11-19 16:14:50 +00:00
|
|
|
mtpMsgId prepareToSend(
|
2019-12-02 13:10:19 +00:00
|
|
|
SerializedRequest &request,
|
2019-11-19 16:14:50 +00:00
|
|
|
mtpMsgId currentLastId,
|
|
|
|
bool forceNewMsgId);
|
2019-11-22 09:15:38 +00:00
|
|
|
mtpMsgId replaceMsgId(
|
2019-12-02 13:10:19 +00:00
|
|
|
SerializedRequest &request,
|
2019-11-22 09:15:38 +00:00
|
|
|
mtpMsgId newId);
|
2018-06-25 18:55:27 +00:00
|
|
|
|
2019-11-22 09:15:38 +00:00
|
|
|
bool sendSecureRequest(
|
2019-12-02 13:10:19 +00:00
|
|
|
SerializedRequest &&request,
|
2019-11-22 09:15:38 +00:00
|
|
|
bool needAnyResponse);
|
2014-05-30 08:53:19 +00:00
|
|
|
mtpRequestId wasSent(mtpMsgId msgId) const;
|
|
|
|
|
2019-07-18 14:06:38 +00:00
|
|
|
[[nodiscard]] HandleResult handleOneReceived(const mtpPrime *from, const mtpPrime *end, uint64 msgId, int32 serverTime, uint64 serverSalt, bool badTime);
|
2019-11-22 09:06:48 +00:00
|
|
|
[[nodiscard]] HandleResult handleBindResponse(
|
|
|
|
mtpMsgId requestMsgId,
|
|
|
|
const mtpBuffer &response);
|
2014-05-30 08:53:19 +00:00
|
|
|
mtpBuffer ungzip(const mtpPrime *from, const mtpPrime *end) const;
|
2019-12-02 11:34:14 +00:00
|
|
|
void handleMsgsStates(const QVector<MTPlong> &ids, const QByteArray &states);
|
2014-05-30 08:53:19 +00:00
|
|
|
|
2019-11-18 12:53:37 +00:00
|
|
|
// _sessionDataMutex must be locked for read.
|
2019-11-27 14:22:22 +00:00
|
|
|
bool setState(int state, int ifState = kUpdateStateAlways);
|
2017-02-24 17:15:41 +00:00
|
|
|
|
2018-04-24 19:09:20 +00:00
|
|
|
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, int32 serverTime, uint64 serverSalt);
|
|
|
|
|
2020-05-12 13:31:57 +00:00
|
|
|
// 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);
|
|
|
|
|
2018-04-24 19:09:20 +00:00
|
|
|
// remove msgs with such ids from sessionData->haveSent, add to sessionData->wereAcked
|
|
|
|
void requestsAcked(const QVector<MTPlong> &ids, bool byResponse = false);
|
|
|
|
|
2019-11-18 12:53:37 +00:00
|
|
|
void resend(
|
|
|
|
mtpMsgId msgId,
|
|
|
|
crl::time msCanWait = 0,
|
2019-11-19 11:55:39 +00:00
|
|
|
bool forceContainer = false);
|
2019-11-22 09:06:48 +00:00
|
|
|
void resendAll();
|
|
|
|
void clearSpecialMsgId(mtpMsgId msgId);
|
2018-04-24 19:09:20 +00:00
|
|
|
|
2019-11-21 10:37:39 +00:00
|
|
|
[[nodiscard]] DcType tryAcquireKeyCreation();
|
2019-11-13 14:12:04 +00:00
|
|
|
void resetSession();
|
2019-11-15 13:04:32 +00:00
|
|
|
void checkAuthKey();
|
|
|
|
void authKeyChecked();
|
2019-11-19 10:10:51 +00:00
|
|
|
void destroyTemporaryKey();
|
2019-11-20 09:16:53 +00:00
|
|
|
void clearUnboundKeyCreator();
|
|
|
|
void releaseKeyCreationOnFail();
|
2019-11-20 11:50:19 +00:00
|
|
|
void applyAuthKey(AuthKeyPtr &&encryptionKey);
|
2019-12-09 14:32:51 +00:00
|
|
|
[[nodiscard]] bool noMediaKeyWithExistingRegularKey() const;
|
2019-11-20 13:33:45 +00:00
|
|
|
bool destroyOldEnoughPersistentKey();
|
2017-03-09 18:13:55 +00:00
|
|
|
|
2019-11-20 10:41:14 +00:00
|
|
|
void setCurrentKeyId(uint64 newKeyId);
|
|
|
|
void changeSessionId();
|
|
|
|
[[nodiscard]] bool markSessionAsStarted();
|
|
|
|
[[nodiscard]] uint32 nextRequestSeqNumber(bool needAck);
|
|
|
|
|
2019-11-21 10:37:39 +00:00
|
|
|
[[nodiscard]] bool realDcTypeChanged();
|
2020-04-07 11:19:52 +00:00
|
|
|
[[nodiscard]] MTPVector<MTPJSONObjectValue> prepareInitParams();
|
2019-11-21 10:37:39 +00:00
|
|
|
|
2019-11-18 12:53:37 +00:00
|
|
|
const not_null<Instance*> _instance;
|
2019-11-21 10:37:39 +00:00
|
|
|
const ShiftedDcId _shiftedDcId = 0;
|
|
|
|
DcType _realDcType = DcType();
|
|
|
|
DcType _currentDcType = DcType();
|
2017-02-24 17:15:41 +00:00
|
|
|
|
2019-11-21 10:37:39 +00:00
|
|
|
mutable QReadWriteLock _stateMutex;
|
2019-11-27 14:22:22 +00:00
|
|
|
int _state = DisconnectedState;
|
2014-05-30 08:53:19 +00:00
|
|
|
|
2016-12-07 13:32:25 +00:00
|
|
|
bool _needSessionReset = false;
|
2014-08-01 11:09:46 +00:00
|
|
|
|
2018-04-24 19:09:20 +00:00
|
|
|
ConnectionPointer _connection;
|
|
|
|
std::vector<TestConnection> _testConnections;
|
2019-02-19 06:57:53 +00:00
|
|
|
crl::time _startedConnectingAt = 0;
|
2014-05-30 08:53:19 +00:00
|
|
|
|
2018-04-24 19:09:20 +00:00
|
|
|
base::Timer _retryTimer; // exp retry timer
|
|
|
|
int _retryTimeout = 1;
|
|
|
|
qint64 _retryWillFinish = 0;
|
2014-05-30 08:53:19 +00:00
|
|
|
|
2018-04-24 19:09:20 +00:00
|
|
|
base::Timer _oldConnectionTimer;
|
|
|
|
bool _oldConnection = true;
|
2014-05-30 08:53:19 +00:00
|
|
|
|
2018-04-24 19:09:20 +00:00
|
|
|
base::Timer _waitForConnectedTimer;
|
|
|
|
base::Timer _waitForReceivedTimer;
|
|
|
|
base::Timer _waitForBetterTimer;
|
2019-02-19 06:57:53 +00:00
|
|
|
crl::time _waitForReceived = 0;
|
|
|
|
crl::time _waitForConnected = 0;
|
2019-11-14 07:13:17 +00:00
|
|
|
crl::time _firstSentAt = -1;
|
2014-05-30 08:53:19 +00:00
|
|
|
|
2016-12-07 13:32:25 +00:00
|
|
|
mtpPingId _pingId = 0;
|
|
|
|
mtpPingId _pingIdToSend = 0;
|
2019-02-19 06:57:53 +00:00
|
|
|
crl::time _pingSendAt = 0;
|
2016-12-07 13:32:25 +00:00
|
|
|
mtpMsgId _pingMsgId = 0;
|
2018-04-24 19:09:20 +00:00
|
|
|
base::Timer _pingSender;
|
2019-11-20 10:41:14 +00:00
|
|
|
base::Timer _checkSentRequestsTimer;
|
2014-05-30 08:53:19 +00:00
|
|
|
|
2019-11-18 12:53:37 +00:00
|
|
|
std::shared_ptr<SessionData> _sessionData;
|
2019-12-02 13:10:19 +00:00
|
|
|
std::unique_ptr<SessionOptions> _options;
|
2019-11-20 11:50:19 +00:00
|
|
|
AuthKeyPtr _encryptionKey;
|
2019-11-20 10:41:14 +00:00
|
|
|
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;
|
2019-12-02 13:10:19 +00:00
|
|
|
ReceivedIdsManager _receivedMessageIds;
|
2019-11-22 09:06:48 +00:00
|
|
|
base::flat_map<mtpMsgId, mtpRequestId> _resendingIds;
|
|
|
|
base::flat_map<mtpMsgId, mtpRequestId> _ackedIds;
|
2019-12-02 13:10:19 +00:00
|
|
|
base::flat_map<mtpMsgId, SerializedRequest> _stateAndResendRequests;
|
2019-12-02 10:32:09 +00:00
|
|
|
base::flat_map<mtpMsgId, SentContainer> _sentContainers;
|
2016-03-24 08:57:11 +00:00
|
|
|
|
2019-12-02 13:10:19 +00:00
|
|
|
std::unique_ptr<BoundKeyCreator> _keyCreator;
|
2019-11-22 09:06:48 +00:00
|
|
|
mtpMsgId _bindMsgId = 0;
|
2019-12-02 13:30:33 +00:00
|
|
|
crl::time _bindMessageSent = 0;
|
2014-05-30 08:53:19 +00:00
|
|
|
|
|
|
|
};
|
2016-03-24 08:57:11 +00:00
|
|
|
|
2019-12-02 13:10:19 +00:00
|
|
|
} // namespace details
|
2016-03-24 08:57:11 +00:00
|
|
|
} // namespace MTP
|