Sync local time with HTTP 'Date' header value.

This commit is contained in:
John Preston 2019-07-10 17:03:48 +02:00
parent c894ce30c4
commit 68b1024dd4
24 changed files with 356 additions and 55 deletions

View file

@ -24,11 +24,13 @@ ConfigLoader::ConfigLoader(
not_null<Instance*> instance,
const QString &phone,
RPCDoneHandlerPtr onDone,
RPCFailHandlerPtr onFail)
RPCFailHandlerPtr onFail,
Fn<void(TimeId)> updateHttpUnixtime)
: _instance(instance)
, _phone(phone)
, _doneHandler(onDone)
, _failHandler(onFail) {
, _failHandler(onFail)
, _updateHttpUnixtime(updateHttpUnixtime) {
_enumDCTimer.setCallback([this] { enumerate(); });
_specialEnumTimer.setCallback([this] { sendSpecialRequest(); });
}
@ -129,7 +131,7 @@ void ConfigLoader::createSpecialLoader() {
int port,
bytes::const_span secret) {
addSpecialEndpoint(dcId, ip, port, secret);
}, _phone);
}, _updateHttpUnixtime, _phone);
}
void ConfigLoader::addSpecialEndpoint(

View file

@ -25,7 +25,8 @@ public:
not_null<Instance*> instance,
const QString &phone,
RPCDoneHandlerPtr onDone,
RPCFailHandlerPtr onFail);
RPCFailHandlerPtr onFail,
Fn<void(TimeId)> updateHttpUnixtime);
~ConfigLoader();
void load();
@ -69,6 +70,7 @@ private:
RPCDoneHandlerPtr _doneHandler;
RPCFailHandlerPtr _failHandler;
Fn<void(TimeId)> _updateHttpUnixtime;
};

View file

@ -379,6 +379,9 @@ void ConnectionPrivate::appendTestConnection(
connect(weak, &AbstractConnection::disconnected, [=] {
onDisconnected(weak);
});
connect(weak, &AbstractConnection::syncTimeRequest, [=] {
_instance->syncHttpUnixtime();
});
InvokeQueued(_testConnections.back().data, [=] {
weak->connectToServer(ip, port, protocolSecret, getProtocolDcId());
@ -1332,7 +1335,7 @@ void ConnectionPrivate::waitConnectedFailed() {
_waitForConnected = std::min(maxTimeout, 2 * _waitForConnected);
}
doDisconnect();
connectingTimedOut();
restarted = true;
DEBUG_LOG(("MTP Info: immediate restart!"));
@ -1343,6 +1346,13 @@ void ConnectionPrivate::waitBetterFailed() {
confirmBestConnection();
}
void ConnectionPrivate::connectingTimedOut() {
for (const auto &connection : _testConnections) {
connection.data->timedOut();
}
doDisconnect();
}
void ConnectionPrivate::doDisconnect() {
destroyAllConnections();

View file

@ -152,6 +152,7 @@ private:
int priority = 0;
};
void connectToServer(bool afterConfig = false);
void connectingTimedOut();
void doDisconnect();
void restart();
void finishAndDestroy();

View file

@ -165,7 +165,10 @@ ConnectionPointer AbstractConnection::Create(
const ProxyData &proxy) {
auto result = [&] {
if (protocol == DcOptions::Variants::Tcp) {
return ConnectionPointer::New<TcpConnection>(thread, proxy);
return ConnectionPointer::New<TcpConnection>(
instance,
thread,
proxy);
} else {
return ConnectionPointer::New<HttpConnection>(thread, proxy);
}

View file

@ -75,6 +75,8 @@ public:
int port,
const bytes::vector &protocolSecret,
int16 protocolDcId) = 0;
virtual void timedOut() {
}
virtual bool isConnected() const = 0;
virtual bool usingHttpWait() {
return false;
@ -122,6 +124,8 @@ signals:
void connected();
void disconnected();
void syncTimeRequest();
protected:
BuffersQueue _receivedQueue; // list of received packets, not processed yet
bool _sentEncrypted = false;

View file

@ -237,13 +237,17 @@ auto TcpConnection::Protocol::Create(bytes::const_span secret)
Unexpected("Secret bytes in TcpConnection::Protocol::Create.");
}
TcpConnection::TcpConnection(QThread *thread, const ProxyData &proxy)
TcpConnection::TcpConnection(
not_null<Instance*> instance,
QThread *thread,
const ProxyData &proxy)
: AbstractConnection(thread, proxy)
, _instance(instance)
, _checkNonce(rand_value<MTPint128>()) {
}
ConnectionPointer TcpConnection::clone(const ProxyData &proxy) {
return ConnectionPointer::New<TcpConnection>(thread(), proxy);
return ConnectionPointer::New<TcpConnection>(_instance, thread(), proxy);
}
void TcpConnection::ensureAvailableInBuffer(int amount) {
@ -554,7 +558,8 @@ void TcpConnection::connectToServer(
_socket = AbstractSocket::Create(
thread(),
secret,
ToNetworkProxy(_proxy));
ToNetworkProxy(_proxy),
[=] { return _instance->httpUnixtime(); });
_protocolDcId = protocolDcId;
_socket->connected(
@ -577,6 +582,11 @@ void TcpConnection::connectToServer(
socketError();
}, _lifetime);
_socket->syncTimeRequests(
) | rpl::start_with_next([=] {
emit syncTimeRequest();
}, _lifetime);
_socket->connectToHost(_address, _port);
}
@ -628,6 +638,12 @@ void TcpConnection::socketPacket(bytes::const_span bytes) {
}
}
void TcpConnection::timedOut() {
if (_socket) {
_socket->timedOut();
}
}
bool TcpConnection::isConnected() const {
return (_status == Status::Ready);
}

View file

@ -17,7 +17,10 @@ class AbstractSocket;
class TcpConnection : public AbstractConnection {
public:
TcpConnection(QThread *thread, const ProxyData &proxy);
TcpConnection(
not_null<Instance*> instance,
QThread *thread,
const ProxyData &proxy);
ConnectionPointer clone(const ProxyData &proxy) override;
@ -30,6 +33,7 @@ public:
int port,
const bytes::vector &protocolSecret,
int16 protocolDcId) override;
void timedOut() override;
bool isConnected() const override;
bool requiresExtendedPadding() const override;
@ -63,6 +67,7 @@ private:
return *reinterpret_cast<uint32*>(ch);
}
const not_null<Instance*> _instance;
std::unique_ptr<AbstractSocket> _socket;
bool _connectionStarted = false;

View file

@ -16,9 +16,10 @@ namespace internal {
std::unique_ptr<AbstractSocket> AbstractSocket::Create(
not_null<QThread*> thread,
const bytes::vector &secret,
const QNetworkProxy &proxy) {
const QNetworkProxy &proxy,
Fn<int32()> unixtime) {
if (secret.size() >= 21 && secret[0] == bytes::type(0xEE)) {
return std::make_unique<TlsSocket>(thread, secret, proxy);
return std::make_unique<TlsSocket>(thread, secret, proxy, unixtime);
} else {
return std::make_unique<TcpSocket>(thread, proxy);
}

View file

@ -8,6 +8,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#pragma once
#include "base/bytes.h"
#include "base/basic_types.h"
namespace MTP {
namespace internal {
@ -17,7 +18,8 @@ public:
static std::unique_ptr<AbstractSocket> Create(
not_null<QThread*> thread,
const bytes::vector &secret,
const QNetworkProxy &proxy);
const QNetworkProxy &proxy,
Fn<int32()> unixtime);
explicit AbstractSocket(not_null<QThread*> thread) {
moveToThread(thread);
@ -36,8 +38,12 @@ public:
[[nodiscard]] rpl::producer<> error() const {
return _error.events();
}
[[nodiscard]] rpl::producer<> syncTimeRequests() const {
return _syncTimeRequests.events();
}
virtual void connectToHost(const QString &address, int port) = 0;
virtual void timedOut() = 0;
[[nodiscard]] virtual bool isConnected() = 0;
[[nodiscard]] virtual bool hasBytesAvailable() = 0;
[[nodiscard]] virtual int64 read(bytes::span buffer) = 0;
@ -52,6 +58,7 @@ protected:
rpl::event_stream<> _disconnected;
rpl::event_stream<> _readyRead;
rpl::event_stream<> _error;
rpl::event_stream<> _syncTimeRequests;
};

View file

@ -42,31 +42,36 @@ public:
void setGoodProxyDomain(const QString &host, const QString &ip);
void suggestMainDcId(DcId mainDcId);
void setMainDcId(DcId mainDcId);
DcId mainDcId() const;
[[nodiscard]] DcId mainDcId() const;
void setKeyForWrite(DcId dcId, const AuthKeyPtr &key);
AuthKeysList getKeysForWrite() const;
[[nodiscard]] AuthKeysList getKeysForWrite() const;
void addKeysForDestroy(AuthKeysList &&keys);
not_null<DcOptions*> dcOptions();
[[nodiscard]] not_null<DcOptions*> dcOptions();
// Thread safe.
QString deviceModel() const;
QString systemVersion() const;
[[nodiscard]] QString deviceModel() const;
[[nodiscard]] QString systemVersion() const;
// Main thread.
void requestConfig();
void requestConfigIfOld();
void requestCDNConfig();
void setUserPhone(const QString &phone);
void badConfigurationError();
// Thread safe.
void syncHttpUnixtime();
[[nodiscard]] int32 httpUnixtime() const;
void restart();
void restart(ShiftedDcId shiftedDcId);
int32 dcstate(ShiftedDcId shiftedDcId = 0);
QString dctransport(ShiftedDcId shiftedDcId = 0);
[[nodiscard]] int32 dcstate(ShiftedDcId shiftedDcId = 0);
[[nodiscard]] QString dctransport(ShiftedDcId shiftedDcId = 0);
void ping();
void cancel(mtpRequestId requestId);
int32 state(mtpRequestId requestId); // < 0 means waiting for such count of ms
[[nodiscard]] int32 state(mtpRequestId requestId); // < 0 means waiting for such count of ms
void killSession(ShiftedDcId shiftedDcId);
void killSession(std::unique_ptr<internal::Session> session);
void stopSession(ShiftedDcId shiftedDcId);
@ -123,9 +128,6 @@ public:
bool isKeysDestroyer() const {
return (_mode == Instance::Mode::KeysDestroyer);
}
bool isSpecialConfigRequester() const {
return (_mode == Instance::Mode::SpecialConfigRequester);
}
void scheduleKeyDestroy(ShiftedDcId shiftedDcId);
void performKeyDestroy(ShiftedDcId shiftedDcId);
@ -166,6 +168,7 @@ private:
void clearCallbacks(const std::vector<RPCCallbackClear> &ids);
void checkDelayedRequests();
[[nodiscard]] Fn<void(TimeId)> updateHttpUnixtime();
not_null<Instance*> _instance;
not_null<DcOptions*> _dcOptions;
@ -186,10 +189,13 @@ private:
std::unique_ptr<internal::ConfigLoader> _configLoader;
std::unique_ptr<DomainResolver> _domainResolver;
std::unique_ptr<SpecialConfigRequest> _httpUnixtimeLoader;
QString _userPhone;
mtpRequestId _cdnConfigLoadRequestId = 0;
crl::time _lastConfigLoadedTime = 0;
crl::time _configExpiresAt = 0;
std::atomic<bool> _httpUnixtimeValid = false;
std::atomic<TimeId> _httpUnixtimeShift = 0;
std::map<DcId, AuthKeyPtr> _keysForWrite;
mutable QReadWriteLock _keysForWriteLock;
@ -407,7 +413,8 @@ void Instance::Private::requestConfig() {
_instance,
_userPhone,
rpcDone([=](const MTPConfig &result) { configLoadDone(result); }),
rpcFail([=](const RPCError &error) { return configLoadFail(error); }));
rpcFail([=](const RPCError &error) { return configLoadFail(error); }),
updateHttpUnixtime());
_configLoader->load();
}
@ -426,6 +433,35 @@ void Instance::Private::badConfigurationError() {
}
}
int32 Instance::Private::httpUnixtime() const {
return unixtime() + _httpUnixtimeShift;
}
void Instance::Private::syncHttpUnixtime() {
if (_httpUnixtimeValid) {
return;
}
InvokeQueued(_instance, [=] {
if (_httpUnixtimeValid || _httpUnixtimeLoader) {
return;
}
_httpUnixtimeLoader = std::make_unique<SpecialConfigRequest>(
updateHttpUnixtime());
});
}
Fn<void(TimeId)> Instance::Private::updateHttpUnixtime() {
return [=](TimeId httpUnixtime) {
_httpUnixtimeValid = true;
_httpUnixtimeShift = httpUnixtime - unixtime();
InvokeQueued(_instance, [=] {
if (_httpUnixtimeValid) {
_httpUnixtimeLoader = nullptr;
}
});
};
}
void Instance::Private::requestConfigIfOld() {
const auto timeout = Global::BlockedMode()
? kConfigBecomesOldForBlockedIn
@ -1579,6 +1615,14 @@ void Instance::badConfigurationError() {
_private->badConfigurationError();
}
int32 Instance::httpUnixtime() const {
return _private->httpUnixtime();
}
void Instance::syncHttpUnixtime() {
_private->syncHttpUnixtime();
}
void Instance::requestConfigIfOld() {
_private->requestConfigIfOld();
}

View file

@ -40,7 +40,6 @@ public:
};
enum class Mode {
Normal,
SpecialConfigRequester,
KeysDestroyer,
};
Instance(not_null<DcOptions*> options, Mode mode, Config &&config);
@ -52,20 +51,20 @@ public:
void setGoodProxyDomain(const QString &host, const QString &ip);
void suggestMainDcId(DcId mainDcId);
void setMainDcId(DcId mainDcId);
DcId mainDcId() const;
QString systemLangCode() const;
QString cloudLangCode() const;
QString langPackName() const;
[[nodiscard]] DcId mainDcId() const;
[[nodiscard]] QString systemLangCode() const;
[[nodiscard]] QString cloudLangCode() const;
[[nodiscard]] QString langPackName() const;
// Thread safe.
QString deviceModel() const;
QString systemVersion() const;
[[nodiscard]] QString deviceModel() const;
[[nodiscard]] QString systemVersion() const;
void setKeyForWrite(DcId dcId, const AuthKeyPtr &key);
AuthKeysList getKeysForWrite() const;
[[nodiscard]] AuthKeysList getKeysForWrite() const;
void addKeysForDestroy(AuthKeysList &&keys);
not_null<DcOptions*> dcOptions();
[[nodiscard]] not_null<DcOptions*> dcOptions();
template <typename Request>
mtpRequestId send(
@ -181,6 +180,10 @@ public:
void setUserPhone(const QString &phone);
void badConfigurationError();
// Thread safe.
[[nodiscard]] int32 httpUnixtime() const;
void syncHttpUnixtime();
~Instance();
public slots:

View file

@ -0,0 +1,9 @@
/*
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
*/
#include "mtproto/mtp_pch.h"

View file

@ -0,0 +1,19 @@
/*
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
*/
#include <QtCore/QObject>
#include <QtCore/QThread>
#include <QtNetwork/QNetworkProxy>
#include <QtNetwork/QTcpSocket>
#include <rpl/rpl.h>
#include <crl/crl.h>
#include "base/bytes.h"
#include "logs.h"
#include "scheme.h"

View file

@ -7,6 +7,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
*/
#include "mtproto/mtp_tcp_socket.h"
#include "base/invoke_queued.h"
namespace MTP {
namespace internal {
@ -45,6 +47,9 @@ void TcpSocket::connectToHost(const QString &address, int port) {
_socket.connectToHost(address, port);
}
void TcpSocket::timedOut() {
}
bool TcpSocket::isConnected() {
return (_socket.state() == QAbstractSocket::ConnectedState);
}

View file

@ -17,6 +17,7 @@ public:
TcpSocket(not_null<QThread*> thread, const QNetworkProxy &proxy);
void connectToHost(const QString &address, int port) override;
void timedOut() override;
bool isConnected() override;
bool hasBytesAvailable() override;
int64 read(bytes::span buffer) override;

View file

@ -9,6 +9,10 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "mtproto/mtp_tcp_socket.h"
#include "base/openssl_help.h"
#include "base/bytes.h"
#include "base/invoke_queued.h"
#include <QtCore/QtEndian>
namespace MTP {
namespace internal {
@ -132,7 +136,8 @@ public:
ClientHelloGenerator(
const MTPTlsClientHello &rules,
bytes::const_span domain,
bytes::const_span key);
bytes::const_span key,
Fn<int32()> unixtime);
[[nodiscard]] ClientHello result();
private:
@ -151,6 +156,7 @@ private:
bytes::const_span _domain;
bytes::const_span _key;
Fn<int32()> _unixtime;
bytes::vector _greases;
std::vector<int> _scopeStack;
QByteArray _result;
@ -163,9 +169,11 @@ private:
ClientHelloGenerator::ClientHelloGenerator(
const MTPTlsClientHello &rules,
bytes::const_span domain,
bytes::const_span key)
bytes::const_span key,
Fn<int32()> unixtime)
: _domain(domain)
, _key(key)
, _unixtime(unixtime)
, _greases(PrepareGreases()) {
_result.reserve(kClientHelloLength);
writeBlocks(rules.match([&](const MTPDtlsClientHello &data) {
@ -296,7 +304,7 @@ void ClientHelloGenerator::writeTimestamp() {
sizeof(int32));
auto already = int32();
bytes::copy(bytes::object_as_span(&already), storage);
already ^= qToLittleEndian(int32(unixtime()));
already ^= qToLittleEndian(_unixtime());
bytes::copy(storage, bytes::object_as_span(&already));
_digest = QByteArray(kHelloDigestLength, Qt::Uninitialized);
@ -310,8 +318,9 @@ void ClientHelloGenerator::writeTimestamp() {
[[nodiscard]] ClientHello PrepareClientHello(
const MTPTlsClientHello &rules,
bytes::const_span domain,
bytes::const_span key) {
return ClientHelloGenerator(rules, domain, key).result();
bytes::const_span key,
Fn<int32()> unixtime) {
return ClientHelloGenerator(rules, domain, key, unixtime).result();
}
[[nodiscard]] bool CheckPart(bytes::const_span data, QLatin1String check) {
@ -334,10 +343,13 @@ void ClientHelloGenerator::writeTimestamp() {
TlsSocket::TlsSocket(
not_null<QThread*> thread,
const bytes::vector &secret,
const QNetworkProxy &proxy)
const QNetworkProxy &proxy,
Fn<int32()> unixtime)
: AbstractSocket(thread)
, _secret(secret) {
, _secret(secret)
, _unixtime(unixtime) {
Expects(_secret.size() >= 21 && _secret[0] == bytes::type(0xEE));
Expects(_unixtime != nullptr);
_socket.moveToThread(thread);
_socket.setProxy(proxy);
@ -385,7 +397,8 @@ void TlsSocket::plainConnected() {
const auto hello = PrepareClientHello(
kClientHelloRules,
domainFromSecret(),
keyFromSecret());
keyFromSecret(),
_unixtime);
if (hello.data.isEmpty()) {
LOG(("TLS Error: Could not generate Client Hello!"));
_state = State::Error;
@ -570,6 +583,10 @@ void TlsSocket::connectToHost(const QString &address, int port) {
_socket.connectToHost(address, port);
}
void TlsSocket::timedOut() {
_syncTimeRequests.fire({});
}
bool TlsSocket::isConnected() {
return (_state == State::Connected);
}
@ -648,6 +665,9 @@ int32 TlsSocket::debugState() {
}
void TlsSocket::handleError(int errorCode) {
if (_state != State::Connected) {
_syncTimeRequests.fire({});
}
if (errorCode) {
TcpSocket::LogError(errorCode, _socket.errorString());
}

View file

@ -17,9 +17,11 @@ public:
TlsSocket(
not_null<QThread*> thread,
const bytes::vector &secret,
const QNetworkProxy &proxy);
const QNetworkProxy &proxy,
Fn<int32()> unixtime);
void connectToHost(const QString &address, int port) override;
void timedOut() override;
bool isConnected() override;
bool hasBytesAvailable() override;
int64 read(bytes::span buffer) override;
@ -54,6 +56,7 @@ private:
const bytes::vector _secret;
QTcpSocket _socket;
Fn<int32()> _unixtime;
State _state = State::NotConnected;
QByteArray _incoming;
int _incomingGoodDataOffset = 0;

View file

@ -170,6 +170,52 @@ QByteArray ConcatenateDnsTxtFields(const std::vector<DnsEntry> &response) {
return QStringList(entries.values()).join(QString()).toLatin1();
}
[[nodiscard]] QDateTime ParseHttpDate(const QString &date) {
// Wed, 10 Jul 2019 14:33:38 GMT
static const auto expression = QRegularExpression(
R"(\w\w\w, (\d\d) (\w\w\w) (\d\d\d\d) (\d\d):(\d\d):(\d\d) GMT)");
const auto match = expression.match(date);
if (!match.hasMatch()) {
return QDateTime();
}
const auto number = [&](int index) {
return match.capturedRef(index).toInt();
};
const auto day = number(1);
const auto month = [&] {
static const auto months = {
"Jan",
"Feb",
"Mar",
"Apr",
"May",
"Jun",
"Jul",
"Aug",
"Sep",
"Oct",
"Nov",
"Dec"
};
const auto captured = match.capturedRef(2);
for (auto i = begin(months); i != end(months); ++i) {
if (captured == (*i)) {
return 1 + int(i - begin(months));
}
}
return 0;
}();
const auto year = number(3);
const auto hour = number(4);
const auto minute = number(5);
const auto second = number(6);
return QDateTime(
QDate(year, month, day),
QTime(hour, minute, second),
Qt::UTC);
}
} // namespace
ServiceWebRequest::ServiceWebRequest(not_null<QNetworkReply*> reply)
@ -212,8 +258,10 @@ SpecialConfigRequest::SpecialConfigRequest(
const std::string &ip,
int port,
bytes::const_span secret)> callback,
Fn<void(TimeId)> timeCallback,
const QString &phone)
: _callback(std::move(callback))
, _timeCallback(std::move(timeCallback))
, _phone(phone) {
_manager.setProxy(QNetworkProxy::NoProxy);
_attempts = {
@ -227,6 +275,10 @@ SpecialConfigRequest::SpecialConfigRequest(
sendNextRequest();
}
SpecialConfigRequest::SpecialConfigRequest(Fn<void(TimeId)> timeCallback)
: SpecialConfigRequest(nullptr, std::move(timeCallback), QString()) {
}
void SpecialConfigRequest::sendNextRequest() {
Expects(!_attempts.empty());
@ -272,10 +324,40 @@ void SpecialConfigRequest::performRequest(const Attempt &attempt) {
});
}
void SpecialConfigRequest::handleHeaderUnixtime(
not_null<QNetworkReply*> reply) {
if (!_timeCallback || reply->error() != QNetworkReply::NoError) {
return;
}
const auto date = QString::fromLatin1([&] {
for (const auto &pair : reply->rawHeaderPairs()) {
if (pair.first == "Date") {
return pair.second;
}
}
return QByteArray();
}());
if (date.isEmpty()) {
LOG(("Config Error: No 'Date' header received."));
return;
}
const auto parsed = ParseHttpDate(date);
if (!parsed.isValid()) {
LOG(("Config Error: Bad 'Date' header received: %1").arg(date));
return;
}
_timeCallback(parsed.toTime_t());
}
void SpecialConfigRequest::requestFinished(
Type type,
not_null<QNetworkReply*> reply) {
handleHeaderUnixtime(reply);
const auto result = finalizeRequest(reply);
if (!_callback) {
return;
}
switch (type) {
//case Type::App: handleResponse(result); break;
case Type::Dns: {

View file

@ -31,7 +31,9 @@ public:
const std::string &ip,
int port,
bytes::const_span secret)> callback,
Fn<void(TimeId)> timeCallback,
const QString &phone);
explicit SpecialConfigRequest(Fn<void(TimeId)> timeCallback);
private:
enum class Type {
@ -46,6 +48,7 @@ private:
void sendNextRequest();
void performRequest(const Attempt &attempt);
void requestFinished(Type type, not_null<QNetworkReply*> reply);
void handleHeaderUnixtime(not_null<QNetworkReply*> reply);
QByteArray finalizeRequest(not_null<QNetworkReply*> reply);
void handleResponse(const QByteArray &bytes);
bool decryptSimpleConfig(const QByteArray &bytes);
@ -55,6 +58,7 @@ private:
const std::string &ip,
int port,
bytes::const_span secret)> _callback;
Fn<void(TimeId)> _timeCallback;
QString _phone;
MTPhelp_ConfigSimple _simpleConfig;

View file

@ -83,6 +83,7 @@
'lib_storage.gyp:lib_storage',
'lib_lottie.gyp:lib_lottie',
'lib_ffmpeg.gyp:lib_ffmpeg',
'lib_mtproto.gyp:lib_mtproto',
],
'defines': [

View file

@ -57,6 +57,7 @@
'<(src_loc)/base/flat_set.h',
'<(src_loc)/base/functors.h',
'<(src_loc)/base/index_based_iterator.h',
'<(src_loc)/base/invoke_queued.h',
'<(src_loc)/base/last_used_cache.h',
'<(src_loc)/base/match_method.h',
'<(src_loc)/base/observer.cpp',

View file

@ -0,0 +1,64 @@
# 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
{
'includes': [
'common.gypi',
],
'targets': [{
'target_name': 'lib_mtproto',
'type': 'static_library',
'includes': [
'common.gypi',
'qt.gypi',
'telegram_linux.gypi',
'pch.gypi',
'openssl.gypi',
],
'variables': {
'src_loc': '../SourceFiles',
'res_loc': '../Resources',
'libs_loc': '../../../Libraries',
'official_build_target%': '',
'submodules_loc': '../ThirdParty',
'pch_source': '<(src_loc)/mtproto/mtp_pch.cpp',
'pch_header': '<(src_loc)/mtproto/mtp_pch.h',
},
'defines': [
],
'dependencies': [
'lib_scheme.gyp:lib_scheme',
'crl.gyp:crl',
],
'export_dependent_settings': [
'lib_scheme.gyp:lib_scheme',
],
'conditions': [[ 'build_macold', {
'xcode_settings': {
'OTHER_CPLUSPLUSFLAGS': [ '-nostdinc++' ],
},
'include_dirs': [
'/usr/local/macold/include/c++/v1',
],
}]],
'include_dirs': [
'<(src_loc)',
'<(SHARED_INTERMEDIATE_DIR)',
'<(libs_loc)/range-v3/include',
'<(submodules_loc)/GSL/include',
'<(submodules_loc)/variant/include',
'<(submodules_loc)/crl/src',
],
'sources': [
'<(src_loc)/mtproto/mtp_abstract_socket.cpp',
'<(src_loc)/mtproto/mtp_abstract_socket.h',
'<(src_loc)/mtproto/mtp_tcp_socket.cpp',
'<(src_loc)/mtproto/mtp_tcp_socket.h',
'<(src_loc)/mtproto/mtp_tls_socket.cpp',
'<(src_loc)/mtproto/mtp_tls_socket.h',
],
}],
}

View file

@ -531,12 +531,6 @@
<(src_loc)/mtproto/dedicated_file_loader.h
<(src_loc)/mtproto/facade.cpp
<(src_loc)/mtproto/facade.h
<(src_loc)/mtproto/mtp_abstract_socket.cpp
<(src_loc)/mtproto/mtp_abstract_socket.h
<(src_loc)/mtproto/mtp_tcp_socket.cpp
<(src_loc)/mtproto/mtp_tcp_socket.h
<(src_loc)/mtproto/mtp_tls_socket.cpp
<(src_loc)/mtproto/mtp_tls_socket.h
<(src_loc)/mtproto/mtp_instance.cpp
<(src_loc)/mtproto/mtp_instance.h
<(src_loc)/mtproto/rsa_public_key.cpp