ZaStoGram_desktop/Telegram/SourceFiles/mtproto/session/private/session_private.h
loop-uh 84e2237558
All checks were successful
Desktop source guards / guards (push) Successful in 6s
Rework the WEB proxy data path around measured limits
A stand (test relay with a sink/echo backend, WAN emulator, env-gated
self-test in the client) showed the dev-17 limits, not the relay, capping
throughput: a fixed 1 MiB upload window and 2 MiB download credit, plus
2 file sessions per DC, while every bridge write waited for its own
round trip through the WebView.

- Bridge: frames written in one carrier turn go to the page as one
  batch, up to 4 page calls are in flight, and the injected script
  joins the frames the page posts in one task into one message.
- Windows: the upload window and the shared download credit follow the
  bandwidth-delay product of the credit loop plus 100 ms of queue
  (AdaptiveWindow), with a periodic drain to keep the base honest, a
  per-direction share when both are busy, and a hold while new streams'
  initial credit floods the relay's downlink.
- Upload and download session counts are upstream's again; upload
  frames shrink with a small window.
- Media sessions over MTProxy and WEB drop a regular temporary key
  borrowed from their DC and use the media cluster key: the regular key
  sent to a -N DC was answered with -404 and destroyed in a loop.
- web_carrier summaries report windows, rates, delays and bridge stats.
2026-09-24 03:18:20 +03:00

196 lines
5.4 KiB
C++

/*
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/protocol/mtproto_serialized_request.h"
#include "mtproto/auth/mtproto_auth_key.h"
#include "mtproto/session/private/auth_factory.h"
#include "mtproto/session/private/connection_factory.h"
#include "mtproto/session/private/message_handler.h"
#include "mtproto/session/private/transport.h"
#include "mtproto/session/session_delegate.h"
#include "mtproto/session/session_role.h"
#include "mtproto/session/session_state.h"
namespace MTP {
class Instance;
class RuntimeEnvironment;
enum class ProxyDiagnosticsPhase;
enum class ProxyDiagnosticsSeverity;
namespace details {
class AbstractConnection;
class SessionData;
class SessionDelegate;
class RSAPublicKey;
struct SessionOptions;
class SessionPrivate final : public QObject {
public:
SessionPrivate(
not_null<Instance*> instance,
not_null<SessionDelegate*> delegate,
not_null<QThread*> thread,
std::shared_ptr<SessionData> data,
ShiftedDcId shiftedDcId,
SessionRole role,
uint64 proxyGeneration = 0,
not_null<SessionConnectionFactory*> connectionFactory
= &DefaultSessionConnectionFactory(),
not_null<SessionAuthKeyFactory*> authKeyFactory
= &DefaultSessionAuthKeyFactory());
~SessionPrivate();
[[nodiscard]] int32 getShiftedDcId() const;
void dcOptionsChanged();
void cdnConfigChanged();
[[nodiscard]] int32 getState() const;
[[nodiscard]] QString transport() const;
void updateAuthKey();
void restartNow();
void migrateProxy(uint64 generation);
void sendPingForce();
void tryToSend();
private:
friend class SessionTransport;
friend class SessionMessageHandler;
static constexpr auto kUpdateStateAlways = 666;
struct SentContainer {
crl::time sent = 0;
std::vector<mtpMsgId> messages;
};
void connectToServer(bool afterConfig = false);
void doDisconnect();
void restart();
void onSentSome(uint64 size);
void onReceivedSome();
void handleReceived();
void sendPingByTimer();
void setConnectionNotice(ConnectionNotice notice);
void reportPingTime(crl::time time);
void logMtprotoEvent(
ProxyDiagnosticsPhase phase,
ProxyDiagnosticsSeverity severity,
const QString &message) const;
[[nodiscard]] QString mtprotoLogDc() const;
[[nodiscard]] int16 getProtocolDcId() const;
void checkSentRequests();
mtpMsgId placeToContainer(
SerializedRequest &toSendRequest,
mtpMsgId &bigMsgId,
bool forceNewMsgId,
SerializedRequest &req);
mtpMsgId prepareToSend(
SerializedRequest &request,
mtpMsgId currentLastId,
bool forceNewMsgId);
mtpMsgId replaceMsgId(
SerializedRequest &request,
mtpMsgId newId);
mtpMsgId RegisterSentRequest(
base::flat_map<mtpMsgId, SerializedRequest> &haveSent,
SerializedRequest &request,
mtpMsgId msgId);
bool sendSecureRequest(
SerializedRequest &&request,
bool needAnyResponse);
mtpRequestId wasSent(mtpMsgId msgId) const;
bool setState(int state, int ifState = kUpdateStateAlways);
[[nodiscard]] DcType tryAcquireKeyCreation();
void resetSession();
void checkAuthKey();
void authKeyChecked();
void destroyTemporaryKey();
void clearUnboundKeyCreator();
void releaseKeyCreationOnFail();
void applyAuthKey(AuthKeyPtr &&encryptionKey);
[[nodiscard]] bool noMediaKeyWithExistingRegularKey() const;
void dropMismatchedTemporaryKey();
bool destroyOldEnoughPersistentKey();
void setCurrentKeyId(uint64 newKeyId);
void changeSessionId();
[[nodiscard]] bool markSessionAsStarted();
[[nodiscard]] uint32 nextRequestSeqNumber(bool needAck);
[[nodiscard]] bool realDcTypeChanged();
[[nodiscard]] MTPVector<MTPJSONObjectValue> prepareInitParams();
struct RequestState {
mtpPingId pingId = 0;
mtpPingId pingIdToSend = 0;
crl::time pingSendAt = 0;
crl::time pingSentTime = 0;
mtpMsgId pingMsgId = 0;
QVector<MTPlong> ackData;
QVector<MTPlong> resendData;
base::flat_set<mtpMsgId> stateData;
ReceivedIdsManager receivedIds;
base::flat_map<mtpMsgId, mtpRequestId> resendingIds;
base::flat_map<mtpMsgId, mtpRequestId> ackedIds;
base::flat_map<mtpMsgId, SerializedRequest> stateAndResendRequests;
base::flat_map<mtpMsgId, SentContainer> sentContainers;
};
struct SessionState {
explicit SessionState(std::shared_ptr<SessionData> data);
std::shared_ptr<SessionData> data;
std::unique_ptr<SessionOptions> options;
AuthKeyPtr encryptionKey;
uint64 keyId = 0;
uint64 sessionId = 0;
uint64 sessionSalt = 0;
uint32 messagesCounter = 0;
bool markedAsStarted = false;
bool needReset = false;
};
struct AuthState {
std::unique_ptr<SessionBoundKeyCreator> keyCreator;
mtpMsgId bindMsgId = 0;
crl::time bindMessageSent = 0;
};
const not_null<Instance*> _instance;
const not_null<SessionDelegate*> _delegate;
const not_null<RuntimeEnvironment*> _runtime;
const not_null<SessionConnectionFactory*> _connectionFactory;
const not_null<SessionAuthKeyFactory*> _authKeyFactory;
const ShiftedDcId _shiftedDcId = 0;
const SessionRole _role = SessionRole::Auxiliary;
DcType _realDcType = DcType();
DcType _currentDcType = DcType();
mutable QReadWriteLock _stateMutex;
int _state = DisconnectedState;
SessionTransport _transport;
SessionMessageHandler _messageHandler;
RequestState _requestState;
SessionState _sessionState;
AuthState _authState;
};
} // namespace details
} // namespace MTP