mirror of
https://github.com/telegramdesktop/tdesktop
synced 2025-08-31 06:26:18 +00:00
Resolve domain names for proxy servers.
Also use dc_id-checked auth key creation. Fixes #4695.
This commit is contained in:
@@ -11,6 +11,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
#include "mtproto/dc_options.h"
|
||||
#include "mtproto/dcenter.h"
|
||||
#include "mtproto/config_loader.h"
|
||||
#include "mtproto/special_config_request.h"
|
||||
#include "mtproto/connection.h"
|
||||
#include "mtproto/sender.h"
|
||||
#include "mtproto/rsa_public_key.h"
|
||||
@@ -38,6 +39,8 @@ public:
|
||||
void start(Config &&config);
|
||||
|
||||
void setCurrentProxy(const ProxyData &proxy, bool enabled);
|
||||
void resolveProxyDomain(const QString &host);
|
||||
void setGoodProxyDomain(const QString &host, const QString &ip);
|
||||
void suggestMainDcId(DcId mainDcId);
|
||||
void setMainDcId(DcId mainDcId);
|
||||
DcId mainDcId() const;
|
||||
@@ -126,6 +129,11 @@ private:
|
||||
bool exportFail(const RPCError &error, mtpRequestId requestId);
|
||||
bool onErrorDefault(mtpRequestId requestId, const RPCError &error);
|
||||
|
||||
void applyDomainIps(
|
||||
const QString &host,
|
||||
const QStringList &ips,
|
||||
TimeMs expireAt);
|
||||
|
||||
void logoutGuestDcs();
|
||||
bool logoutGuestDone(mtpRequestId requestId);
|
||||
|
||||
@@ -161,6 +169,7 @@ private:
|
||||
base::set_of_unique_ptr<internal::Connection> _quittingConnections;
|
||||
|
||||
std::unique_ptr<internal::ConfigLoader> _configLoader;
|
||||
std::unique_ptr<DomainResolver> _domainResolver;
|
||||
QString _userPhone;
|
||||
mtpRequestId _cdnConfigLoadRequestId = 0;
|
||||
TimeMs _lastConfigLoadedTime = 0;
|
||||
@@ -203,7 +212,11 @@ private:
|
||||
|
||||
};
|
||||
|
||||
Instance::Private::Private(not_null<Instance*> instance, not_null<DcOptions*> options, Instance::Mode mode) : Sender()
|
||||
Instance::Private::Private(
|
||||
not_null<Instance*> instance,
|
||||
not_null<DcOptions*> options,
|
||||
Instance::Mode mode)
|
||||
: Sender()
|
||||
, _instance(instance)
|
||||
, _dcOptions(options)
|
||||
, _mode(mode) {
|
||||
@@ -283,6 +296,85 @@ void Instance::Private::setCurrentProxy(
|
||||
Global::RefConnectionTypeChanged().notify();
|
||||
}
|
||||
|
||||
void Instance::Private::resolveProxyDomain(const QString &host) {
|
||||
if (!_domainResolver) {
|
||||
_domainResolver = std::make_unique<DomainResolver>([=](
|
||||
const QString &host,
|
||||
const QStringList &ips,
|
||||
TimeMs expireAt) {
|
||||
applyDomainIps(host, ips, expireAt);
|
||||
});
|
||||
}
|
||||
_domainResolver->resolve(host);
|
||||
}
|
||||
|
||||
void Instance::Private::applyDomainIps(
|
||||
const QString &host,
|
||||
const QStringList &ips,
|
||||
TimeMs expireAt) {
|
||||
const auto applyToProxy = [&](ProxyData &proxy) {
|
||||
if (!proxy.tryCustomResolve() || proxy.host != host) {
|
||||
return false;
|
||||
}
|
||||
proxy.resolvedExpireAt = expireAt;
|
||||
auto copy = ips;
|
||||
auto ¤t = proxy.resolvedIPs;
|
||||
const auto i = ranges::remove_if(current, [&](const QString &ip) {
|
||||
const auto index = copy.indexOf(ip);
|
||||
if (index < 0) {
|
||||
return true;
|
||||
}
|
||||
copy.removeAt(index);
|
||||
return false;
|
||||
});
|
||||
if (i == end(current) && copy.isEmpty()) {
|
||||
// Even if the proxy was changed already, we still want
|
||||
// to refreshOptions in all sessions across all instances.
|
||||
return true;
|
||||
}
|
||||
current.erase(i, end(current));
|
||||
for (const auto &ip : copy) {
|
||||
proxy.resolvedIPs.push_back(ip);
|
||||
}
|
||||
return true;
|
||||
};
|
||||
for (auto &proxy : Global::RefProxiesList()) {
|
||||
applyToProxy(proxy);
|
||||
}
|
||||
if (applyToProxy(Global::RefSelectedProxy()) && Global::UseProxy()) {
|
||||
for (auto &session : _sessions) {
|
||||
session.second->refreshOptions();
|
||||
}
|
||||
}
|
||||
emit _instance->proxyDomainResolved(host, ips, expireAt);
|
||||
}
|
||||
|
||||
void Instance::Private::setGoodProxyDomain(
|
||||
const QString &host,
|
||||
const QString &ip) {
|
||||
const auto applyToProxy = [&](ProxyData &proxy) {
|
||||
if (!proxy.tryCustomResolve() || proxy.host != host) {
|
||||
return false;
|
||||
}
|
||||
auto ¤t = proxy.resolvedIPs;
|
||||
auto i = ranges::find(current, ip);
|
||||
if (i == end(current) || i == begin(current)) {
|
||||
return false;
|
||||
}
|
||||
while (i != begin(current)) {
|
||||
const auto j = i--;
|
||||
std::swap(*i, *j);
|
||||
}
|
||||
return true;
|
||||
};
|
||||
for (auto &proxy : Global::RefProxiesList()) {
|
||||
applyToProxy(proxy);
|
||||
}
|
||||
if (applyToProxy(Global::RefSelectedProxy()) && Global::UseProxy()) {
|
||||
Sandbox::refreshGlobalProxy();
|
||||
}
|
||||
}
|
||||
|
||||
void Instance::Private::suggestMainDcId(DcId mainDcId) {
|
||||
if (_mainDcIdForced) return;
|
||||
setMainDcId(mainDcId);
|
||||
@@ -503,8 +595,11 @@ void Instance::Private::stopSession(ShiftedDcId shiftedDcId) {
|
||||
}
|
||||
|
||||
void Instance::Private::reInitConnection(DcId dcId) {
|
||||
killSession(dcId);
|
||||
getSession(dcId)->notifyLayerInited(false);
|
||||
for (auto &session : _sessions) {
|
||||
if (bareDcId(session.second->getDcWithShift()) == dcId) {
|
||||
session.second->reInitConnection();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Instance::Private::logout(
|
||||
@@ -1376,6 +1471,14 @@ void Instance::setCurrentProxy(const ProxyData &proxy, bool enabled) {
|
||||
_private->setCurrentProxy(proxy, enabled);
|
||||
}
|
||||
|
||||
void Instance::resolveProxyDomain(const QString &host) {
|
||||
_private->resolveProxyDomain(host);
|
||||
}
|
||||
|
||||
void Instance::setGoodProxyDomain(const QString &host, const QString &ip) {
|
||||
_private->setGoodProxyDomain(host, ip);
|
||||
}
|
||||
|
||||
void Instance::suggestMainDcId(DcId mainDcId) {
|
||||
_private->suggestMainDcId(mainDcId);
|
||||
}
|
||||
|
Reference in New Issue
Block a user