diff --git a/Telegram/SourceFiles/mtproto/details/mtproto_dcenter.cpp b/Telegram/SourceFiles/mtproto/details/mtproto_dcenter.cpp index d0034d4ff2..7dbf0a6023 100644 --- a/Telegram/SourceFiles/mtproto/details/mtproto_dcenter.cpp +++ b/Telegram/SourceFiles/mtproto/details/mtproto_dcenter.cpp @@ -48,6 +48,13 @@ const char *NameOfType(CreatingKeyType type) { } // namespace + +TemporaryKeyType TemporaryKeyTypeByDcType(DcType type) { + return (type == DcType::MediaCluster) + ? TemporaryKeyType::MediaCluster + : TemporaryKeyType::Regular; +} + Dcenter::Dcenter(DcId dcId, AuthKeyPtr &&key) : _id(dcId) , _persistentKey(std::move(key)) { @@ -102,23 +109,24 @@ void Dcenter::setConnectionInited(bool connectionInited) { _connectionInited = connectionInited; } -CreatingKeyType Dcenter::acquireKeyCreation(TemporaryKeyType type) { +CreatingKeyType Dcenter::acquireKeyCreation(DcType type) { QReadLocker lock(&_mutex); - const auto index = IndexByType(type); + const auto keyType = TemporaryKeyTypeByDcType(type); + const auto index = IndexByType(keyType); auto &key = _temporaryKeys[index]; if (key != nullptr) { return CreatingKeyType::None; } auto expected = false; const auto regular = IndexByType(TemporaryKeyType::Regular); - if (type == TemporaryKeyType::MediaCluster && _temporaryKeys[regular]) { + if (keyType == TemporaryKeyType::MediaCluster && _temporaryKeys[regular]) { return !_creatingKeys[index].compare_exchange_strong(expected, true) ? CreatingKeyType::None : CreatingKeyType::TemporaryMediaCluster; } return !_creatingKeys[regular].compare_exchange_strong(expected, true) ? CreatingKeyType::None - : !_persistentKey + : (type != DcType::Cdn && !_persistentKey) ? CreatingKeyType::Persistent : CreatingKeyType::TemporaryRegular; } @@ -132,10 +140,6 @@ bool Dcenter::releaseKeyCreationOnDone( Expects(temporaryKey != nullptr); QWriteLocker lock(&_mutex); - if (type != CreatingKeyType::Persistent - && _persistentKey != persistentKeyUsedForBind) { - return false; - } if (type == CreatingKeyType::Persistent) { _persistentKey = persistentKeyUsedForBind; } else if (_persistentKey != persistentKeyUsedForBind) { diff --git a/Telegram/SourceFiles/mtproto/details/mtproto_dcenter.h b/Telegram/SourceFiles/mtproto/details/mtproto_dcenter.h index 0418e09e40..651dcf1715 100644 --- a/Telegram/SourceFiles/mtproto/details/mtproto_dcenter.h +++ b/Telegram/SourceFiles/mtproto/details/mtproto_dcenter.h @@ -14,6 +14,7 @@ namespace MTP { class Instance; class AuthKey; using AuthKeyPtr = std::shared_ptr; +enum class DcType; namespace details { @@ -29,6 +30,8 @@ enum class CreatingKeyType { TemporaryMediaCluster }; +[[nodiscard]] TemporaryKeyType TemporaryKeyTypeByDcType(DcType type); + class Dcenter : public QObject { public: // Main thread. @@ -38,7 +41,7 @@ public: [[nodiscard]] DcId id() const; [[nodiscard]] AuthKeyPtr getPersistentKey() const; [[nodiscard]] AuthKeyPtr getTemporaryKey(TemporaryKeyType type) const; - [[nodiscard]] CreatingKeyType acquireKeyCreation(TemporaryKeyType type); + [[nodiscard]] CreatingKeyType acquireKeyCreation(DcType type); bool releaseKeyCreationOnDone( CreatingKeyType type, const AuthKeyPtr &temporaryKey, diff --git a/Telegram/SourceFiles/mtproto/session.cpp b/Telegram/SourceFiles/mtproto/session.cpp index 563f8de2ff..f850e99560 100644 --- a/Telegram/SourceFiles/mtproto/session.cpp +++ b/Telegram/SourceFiles/mtproto/session.cpp @@ -108,7 +108,7 @@ AuthKeyPtr SessionData::getPersistentKey() const { return _owner ? _owner->getPersistentKey() : nullptr; } -CreatingKeyType SessionData::acquireKeyCreation(TemporaryKeyType type) { +CreatingKeyType SessionData::acquireKeyCreation(DcType type) { QMutexLocker lock(&_ownerMutex); return _owner ? _owner->acquireKeyCreation(type) : CreatingKeyType::None; } @@ -124,6 +124,14 @@ bool SessionData::releaseKeyCreationOnDone( : false; } +bool SessionData::releaseCdnKeyCreationOnDone( + const AuthKeyPtr &temporaryKey) { + QMutexLocker lock(&_ownerMutex); + return _owner + ? _owner->releaseCdnKeyCreationOnDone(temporaryKey) + : false; +} + void SessionData::releaseKeyCreationOnFail() { QMutexLocker lock(&_ownerMutex); if (_owner) { @@ -441,7 +449,7 @@ void Session::sendPrepared( } } -CreatingKeyType Session::acquireKeyCreation(TemporaryKeyType type) { +CreatingKeyType Session::acquireKeyCreation(DcType type) { Expects(_myKeyCreation == CreatingKeyType::None); _myKeyCreation = _dc->acquireKeyCreation(type); @@ -454,6 +462,21 @@ bool Session::releaseKeyCreationOnDone( Expects(_myKeyCreation != CreatingKeyType::None); Expects(persistentKeyUsedForBind != nullptr); + return releaseGenericKeyCreationOnDone( + temporaryKey, + persistentKeyUsedForBind); +} + +bool Session::releaseCdnKeyCreationOnDone( + const AuthKeyPtr &temporaryKey) { + Expects(_myKeyCreation == CreatingKeyType::TemporaryRegular); + + return releaseGenericKeyCreationOnDone(temporaryKey, nullptr); +} + +bool Session::releaseGenericKeyCreationOnDone( + const AuthKeyPtr &temporaryKey, + const AuthKeyPtr &persistentKeyUsedForBind) { const auto wasKeyCreation = std::exchange( _myKeyCreation, CreatingKeyType::None); diff --git a/Telegram/SourceFiles/mtproto/session.h b/Telegram/SourceFiles/mtproto/session.h index 0e91698341..dc8b152c68 100644 --- a/Telegram/SourceFiles/mtproto/session.h +++ b/Telegram/SourceFiles/mtproto/session.h @@ -19,6 +19,7 @@ namespace MTP { class Instance; class AuthKey; using AuthKeyPtr = std::shared_ptr; +enum class DcType; namespace details { @@ -100,10 +101,12 @@ public: [[nodiscard]] bool connectionInited() const; [[nodiscard]] AuthKeyPtr getPersistentKey() const; [[nodiscard]] AuthKeyPtr getTemporaryKey(TemporaryKeyType type) const; - [[nodiscard]] CreatingKeyType acquireKeyCreation(TemporaryKeyType type); + [[nodiscard]] CreatingKeyType acquireKeyCreation(DcType type); [[nodiscard]] bool releaseKeyCreationOnDone( const AuthKeyPtr &temporaryKey, const AuthKeyPtr &persistentKeyUsedForBind); + [[nodiscard]] bool releaseCdnKeyCreationOnDone( + const AuthKeyPtr &temporaryKey); void releaseKeyCreationOnFail(); void destroyTemporaryKey(uint64 keyId); @@ -161,10 +164,11 @@ public: crl::time msCanWait = 0); // SessionPrivate thread. - [[nodiscard]] CreatingKeyType acquireKeyCreation(TemporaryKeyType type); + [[nodiscard]] CreatingKeyType acquireKeyCreation(DcType type); [[nodiscard]] bool releaseKeyCreationOnDone( const AuthKeyPtr &temporaryKey, const AuthKeyPtr &persistentKeyUsedForBind); + [[nodiscard]] bool releaseCdnKeyCreationOnDone(const AuthKeyPtr &temporaryKey); void releaseKeyCreationOnFail(); void destroyTemporaryKey(uint64 keyId); @@ -193,6 +197,10 @@ private: const RPCFailHandlerPtr &onFail, const RPCError &err); + [[nodiscard]] bool releaseGenericKeyCreationOnDone( + const AuthKeyPtr &temporaryKey, + const AuthKeyPtr &persistentKeyUsedForBind); + const not_null _instance; const ShiftedDcId _shiftedDcId = 0; const not_null _dc; diff --git a/Telegram/SourceFiles/mtproto/session_private.cpp b/Telegram/SourceFiles/mtproto/session_private.cpp index 56c4fb1e74..18adb6f62f 100644 --- a/Telegram/SourceFiles/mtproto/session_private.cpp +++ b/Telegram/SourceFiles/mtproto/session_private.cpp @@ -77,12 +77,6 @@ using namespace details; return idsStr + "]"; } -[[nodiscard]] TemporaryKeyType TemporaryKeyTypeByDcType(DcType type) { - return (type == DcType::MediaCluster) - ? TemporaryKeyType::MediaCluster - : TemporaryKeyType::Regular; -} - void WrapInvokeAfter( SerializedRequest &to, const SerializedRequest &from, @@ -2349,8 +2343,7 @@ DcType SessionPrivate::tryAcquireKeyCreation() { return _realDcType; } - const auto keyType = TemporaryKeyTypeByDcType(_realDcType); - const auto acquired = _sessionData->acquireKeyCreation(keyType); + const auto acquired = _sessionData->acquireKeyCreation(_realDcType); if (acquired == CreatingKeyType::None) { return _realDcType; } @@ -2384,19 +2377,29 @@ DcType SessionPrivate::tryAcquireKeyCreation() { ).arg(result->persistentServerSalt)); _sessionSalt = result->temporaryServerSalt; - auto key = result->persistentKey - ? std::move(result->persistentKey) - : _sessionData->getPersistentKey(); - if (!key) { - releaseKeyCreationOnFail(); - restart(); - return; - } result->temporaryKey->setExpiresAt(base::unixtime::now() + kTemporaryExpiresIn + kBindKeyAdditionalExpiresTimeout); - _keyCreator->bind(std::move(key)); + if (_realDcType != DcType::Cdn) { + auto key = result->persistentKey + ? std::move(result->persistentKey) + : _sessionData->getPersistentKey(); + if (!key) { + releaseKeyCreationOnFail(); + restart(); + return; + } + _keyCreator->bind(std::move(key)); + } applyAuthKey(std::move(result->temporaryKey)); + if (_realDcType == DcType::Cdn) { + _keyCreator = nullptr; + if (!_sessionData->releaseCdnKeyCreationOnDone(_encryptionKey)) { + restart(); + } else { + _sessionData->queueNeedToResumeAndSend(); + } + } }; delegate.sentSome = [=](uint64 size) { onSentSome(size);