mirror of
https://github.com/telegramdesktop/tdesktop
synced 2025-03-24 12:22:44 +00:00
Try all available endpoints from config.
This commit is contained in:
parent
df4daca15b
commit
95fee543ec
@ -1108,7 +1108,7 @@ void ProxiesBoxController::refreshChecker(Item &item) {
|
|||||||
checker->connectToServer(
|
checker->connectToServer(
|
||||||
QString::fromStdString(endpoints.front().ip),
|
QString::fromStdString(endpoints.front().ip),
|
||||||
endpoints.front().port,
|
endpoints.front().port,
|
||||||
endpoints.front().protocolSecret,
|
endpoints.front().secret,
|
||||||
dcId);
|
dcId);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -52,7 +52,7 @@ mtpRequestId ConfigLoader::sendRequest(ShiftedDcId shiftedDcId) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
DcId ConfigLoader::specialToRealDcId(DcId specialDcId) {
|
DcId ConfigLoader::specialToRealDcId(DcId specialDcId) {
|
||||||
return Instance::Config::kTemporaryMainDc + specialDcId;
|
return getTemporaryIdFromRealDcId(specialDcId);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConfigLoader::terminateRequest() {
|
void ConfigLoader::terminateRequest() {
|
||||||
@ -139,15 +139,18 @@ void ConfigLoader::sendSpecialRequest() {
|
|||||||
|
|
||||||
const auto weak = base::make_weak(this);
|
const auto weak = base::make_weak(this);
|
||||||
const auto index = rand_value<uint32>() % _specialEndpoints.size();
|
const auto index = rand_value<uint32>() % _specialEndpoints.size();
|
||||||
const auto secret = bytes::vector();
|
|
||||||
const auto endpoint = _specialEndpoints.begin() + index;
|
const auto endpoint = _specialEndpoints.begin() + index;
|
||||||
_specialEnumCurrent = specialToRealDcId(endpoint->dcId);
|
_specialEnumCurrent = specialToRealDcId(endpoint->dcId);
|
||||||
|
|
||||||
|
using Flag = MTPDdcOption::Flag;
|
||||||
|
const auto flags = Flag::f_tcpo_only
|
||||||
|
| (endpoint->secret.empty() ? Flag(0) : Flag::f_secret);
|
||||||
_instance->dcOptions()->constructAddOne(
|
_instance->dcOptions()->constructAddOne(
|
||||||
_specialEnumCurrent,
|
_specialEnumCurrent,
|
||||||
MTPDdcOption::Flag::f_tcpo_only,
|
flags,
|
||||||
endpoint->ip,
|
endpoint->ip,
|
||||||
endpoint->port,
|
endpoint->port,
|
||||||
secret);
|
endpoint->secret);
|
||||||
_specialEnumRequest = _instance->send(
|
_specialEnumRequest = _instance->send(
|
||||||
MTPhelp_GetConfig(),
|
MTPhelp_GetConfig(),
|
||||||
rpcDone([weak](const MTPConfig &result) {
|
rpcDone([weak](const MTPConfig &result) {
|
||||||
|
@ -9,6 +9,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||||||
|
|
||||||
#include "base/timer.h"
|
#include "base/timer.h"
|
||||||
#include "base/weak_ptr.h"
|
#include "base/weak_ptr.h"
|
||||||
|
#include "base/bytes.h"
|
||||||
#include "mtproto/rpc_sender.h"
|
#include "mtproto/rpc_sender.h"
|
||||||
|
|
||||||
namespace MTP {
|
namespace MTP {
|
||||||
@ -45,6 +46,7 @@ private:
|
|||||||
DcId dcId;
|
DcId dcId;
|
||||||
std::string ip;
|
std::string ip;
|
||||||
int port;
|
int port;
|
||||||
|
bytes::vector secret;
|
||||||
};
|
};
|
||||||
friend bool operator==(const SpecialEndpoint &a, const SpecialEndpoint &b);
|
friend bool operator==(const SpecialEndpoint &a, const SpecialEndpoint &b);
|
||||||
std::unique_ptr<SpecialConfigRequest> _specialLoader;
|
std::unique_ptr<SpecialConfigRequest> _specialLoader;
|
||||||
|
@ -415,7 +415,6 @@ ConnectionPrivate::ConnectionPrivate(
|
|||||||
, _state(DisconnectedState)
|
, _state(DisconnectedState)
|
||||||
, _shiftedDcId(shiftedDcId)
|
, _shiftedDcId(shiftedDcId)
|
||||||
, _owner(owner)
|
, _owner(owner)
|
||||||
, _configWasFineAt(getms(true))
|
|
||||||
, _retryTimer(thread, [=] { retryByTimer(); })
|
, _retryTimer(thread, [=] { retryByTimer(); })
|
||||||
, _oldConnectionTimer(thread, [=] { markConnectionOld(); })
|
, _oldConnectionTimer(thread, [=] { markConnectionOld(); })
|
||||||
, _waitForConnectedTimer(thread, [=] { waitConnectedFailed(); })
|
, _waitForConnectedTimer(thread, [=] { waitConnectedFailed(); })
|
||||||
@ -1120,7 +1119,7 @@ void ConnectionPrivate::connectToServer(bool afterConfig) {
|
|||||||
static_cast<Variants::Protocol>(protocol),
|
static_cast<Variants::Protocol>(protocol),
|
||||||
QString::fromStdString(endpoint.ip),
|
QString::fromStdString(endpoint.ip),
|
||||||
endpoint.port,
|
endpoint.port,
|
||||||
endpoint.protocolSecret);
|
endpoint.secret);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1142,7 +1141,9 @@ void ConnectionPrivate::connectToServer(bool afterConfig) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (getms(true) - _configWasFineAt > kRequestConfigTimeout) {
|
if (!_startedConnectingAt) {
|
||||||
|
_startedConnectingAt = getms(true);
|
||||||
|
} else if (getms(true) - _startedConnectingAt > kRequestConfigTimeout) {
|
||||||
InvokeQueued(_instance, [instance = _instance] {
|
InvokeQueued(_instance, [instance = _instance] {
|
||||||
instance->requestConfigIfOld();
|
instance->requestConfigIfOld();
|
||||||
});
|
});
|
||||||
@ -1549,6 +1550,7 @@ void ConnectionPrivate::handleReceived() {
|
|||||||
DEBUG_LOG(("MTP Info: marked auth key as checked"));
|
DEBUG_LOG(("MTP Info: marked auth key as checked"));
|
||||||
sessionData->setCheckedKey(true);
|
sessionData->setCheckedKey(true);
|
||||||
}
|
}
|
||||||
|
_startedConnectingAt = TimeMs(0);
|
||||||
|
|
||||||
if (!wasConnected) {
|
if (!wasConnected) {
|
||||||
if (getState() == ConnectedState) {
|
if (getState() == ConnectedState) {
|
||||||
@ -2456,8 +2458,6 @@ void ConnectionPrivate::updateAuthKey() {
|
|||||||
QReadLocker lockFinished(&sessionDataMutex);
|
QReadLocker lockFinished(&sessionDataMutex);
|
||||||
if (!sessionData || !_connection) return;
|
if (!sessionData || !_connection) return;
|
||||||
|
|
||||||
_configWasFineAt = getms(true);
|
|
||||||
|
|
||||||
DEBUG_LOG(("AuthKey Info: Connection updating key from Session, dc %1").arg(_shiftedDcId));
|
DEBUG_LOG(("AuthKey Info: Connection updating key from Session, dc %1").arg(_shiftedDcId));
|
||||||
uint64 newKeyId = 0;
|
uint64 newKeyId = 0;
|
||||||
{
|
{
|
||||||
|
@ -227,7 +227,7 @@ private:
|
|||||||
not_null<Connection*> _owner;
|
not_null<Connection*> _owner;
|
||||||
ConnectionPointer _connection;
|
ConnectionPointer _connection;
|
||||||
std::vector<TestConnection> _testConnections;
|
std::vector<TestConnection> _testConnections;
|
||||||
TimeMs _configWasFineAt = 0;
|
TimeMs _startedConnectingAt = 0;
|
||||||
|
|
||||||
base::Timer _retryTimer; // exp retry timer
|
base::Timer _retryTimer; // exp retry timer
|
||||||
int _retryTimeout = 1;
|
int _retryTimeout = 1;
|
||||||
|
@ -62,7 +62,9 @@ AQIDAQAB\n\
|
|||||||
|
|
||||||
class DcOptions::WriteLocker {
|
class DcOptions::WriteLocker {
|
||||||
public:
|
public:
|
||||||
WriteLocker(DcOptions *that) : _that(that), _lock(&_that->_useThroughLockers) {
|
WriteLocker(not_null<DcOptions*> that)
|
||||||
|
: _that(that)
|
||||||
|
, _lock(&_that->_useThroughLockers) {
|
||||||
}
|
}
|
||||||
~WriteLocker() {
|
~WriteLocker() {
|
||||||
_that->computeCdnDcIds();
|
_that->computeCdnDcIds();
|
||||||
@ -76,7 +78,8 @@ private:
|
|||||||
|
|
||||||
class DcOptions::ReadLocker {
|
class DcOptions::ReadLocker {
|
||||||
public:
|
public:
|
||||||
ReadLocker(const DcOptions *that) : _lock(&that->_useThroughLockers) {
|
ReadLocker(not_null<const DcOptions*> that)
|
||||||
|
: _lock(&that->_useThroughLockers) {
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@ -105,28 +108,18 @@ void DcOptions::constructFromBuiltIn() {
|
|||||||
|
|
||||||
auto bdcs = builtInDcs();
|
auto bdcs = builtInDcs();
|
||||||
for (auto i = 0, l = builtInDcsCount(); i != l; ++i) {
|
for (auto i = 0, l = builtInDcsCount(); i != l; ++i) {
|
||||||
const auto flags = MTPDdcOption::Flags(0);
|
const auto flags = Flag::f_static | 0;
|
||||||
const auto bdc = bdcs[i];
|
const auto bdc = bdcs[i];
|
||||||
const auto idWithShift = MTP::shiftDcId(bdc.id, flags);
|
applyOneGuarded(bdc.id, flags, bdc.ip, bdc.port, {});
|
||||||
_data.emplace(
|
|
||||||
idWithShift,
|
|
||||||
std::vector<Option>(
|
|
||||||
1,
|
|
||||||
Option(bdc.id, flags, bdc.ip, bdc.port, {})));
|
|
||||||
DEBUG_LOG(("MTP Info: adding built in DC %1 connect option: "
|
DEBUG_LOG(("MTP Info: adding built in DC %1 connect option: "
|
||||||
"%2:%3").arg(bdc.id).arg(bdc.ip).arg(bdc.port));
|
"%2:%3").arg(bdc.id).arg(bdc.ip).arg(bdc.port));
|
||||||
}
|
}
|
||||||
|
|
||||||
auto bdcsipv6 = builtInDcsIPv6();
|
auto bdcsipv6 = builtInDcsIPv6();
|
||||||
for (auto i = 0, l = builtInDcsCountIPv6(); i != l; ++i) {
|
for (auto i = 0, l = builtInDcsCountIPv6(); i != l; ++i) {
|
||||||
const auto flags = MTPDdcOption::Flags(MTPDdcOption::Flag::f_ipv6);
|
const auto flags = Flag::f_static | Flag::f_ipv6;
|
||||||
const auto bdc = bdcsipv6[i];
|
const auto bdc = bdcsipv6[i];
|
||||||
const auto idWithShift = MTP::shiftDcId(bdc.id, flags);
|
applyOneGuarded(bdc.id, flags, bdc.ip, bdc.port, {});
|
||||||
_data.emplace(
|
|
||||||
idWithShift,
|
|
||||||
std::vector<Option>(
|
|
||||||
1,
|
|
||||||
Option(bdc.id, flags, bdc.ip, bdc.port, {})));
|
|
||||||
DEBUG_LOG(("MTP Info: adding built in DC %1 IPv6 connect option: "
|
DEBUG_LOG(("MTP Info: adding built in DC %1 IPv6 connect option: "
|
||||||
"%2:%3").arg(bdc.id).arg(bdc.ip).arg(bdc.port));
|
"%2:%3").arg(bdc.id).arg(bdc.ip).arg(bdc.port));
|
||||||
}
|
}
|
||||||
@ -139,62 +132,42 @@ void DcOptions::processFromList(
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto idsChanged = std::vector<DcId>();
|
auto data = [&] {
|
||||||
idsChanged.reserve(options.size());
|
|
||||||
auto shiftedIdsProcessed = std::vector<ShiftedDcId>();
|
|
||||||
shiftedIdsProcessed.reserve(options.size());
|
|
||||||
{
|
|
||||||
WriteLocker lock(this);
|
|
||||||
if (overwrite) {
|
if (overwrite) {
|
||||||
idsChanged.reserve(_data.size());
|
return std::map<DcId, std::vector<Endpoint>>();
|
||||||
|
}
|
||||||
|
ReadLocker lock(this);
|
||||||
|
return _data;
|
||||||
|
}();
|
||||||
|
for (auto &mtpOption : options) {
|
||||||
|
if (mtpOption.type() != mtpc_dcOption) {
|
||||||
|
LOG(("Wrong type in DcOptions: %1").arg(mtpOption.type()));
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
for (auto &mtpOption : options) {
|
|
||||||
if (mtpOption.type() != mtpc_dcOption) {
|
|
||||||
LOG(("Wrong type in DcOptions: %1").arg(mtpOption.type()));
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto &option = mtpOption.c_dcOption();
|
auto &option = mtpOption.c_dcOption();
|
||||||
auto dcId = option.vid.v;
|
auto dcId = option.vid.v;
|
||||||
auto flags = option.vflags.v;
|
auto flags = option.vflags.v;
|
||||||
auto dcIdWithShift = MTP::shiftDcId(dcId, flags);
|
auto ip = std::string(
|
||||||
if (overwrite) {
|
option.vip_address.v.constData(),
|
||||||
if (!base::contains(shiftedIdsProcessed, dcIdWithShift)) {
|
option.vip_address.v.size());
|
||||||
shiftedIdsProcessed.push_back(dcIdWithShift);
|
auto port = option.vport.v;
|
||||||
_data.erase(dcIdWithShift);
|
auto secret = option.has_secret()
|
||||||
}
|
? bytes::make_vector(option.vsecret.v)
|
||||||
}
|
: bytes::vector();
|
||||||
auto ip = std::string(
|
ApplyOneOption(data, dcId, flags, ip, port, secret);
|
||||||
option.vip_address.v.constData(),
|
|
||||||
option.vip_address.v.size());
|
|
||||||
auto port = option.vport.v;
|
|
||||||
auto secret = option.has_secret()
|
|
||||||
? bytes::make_vector(option.vsecret.v)
|
|
||||||
: bytes::vector();
|
|
||||||
if (applyOneGuarded(dcId, flags, ip, port, secret)) {
|
|
||||||
if (!base::contains(idsChanged, dcId)) {
|
|
||||||
idsChanged.push_back(dcId);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (overwrite && shiftedIdsProcessed.size() < _data.size()) {
|
|
||||||
for (auto i = _data.begin(); i != _data.end();) {
|
|
||||||
if (base::contains(shiftedIdsProcessed, i->first)) {
|
|
||||||
++i;
|
|
||||||
} else {
|
|
||||||
const auto &options = i->second;
|
|
||||||
Assert(!options.empty());
|
|
||||||
if (!base::contains(idsChanged, options.front().id)) {
|
|
||||||
idsChanged.push_back(options.front().id);
|
|
||||||
}
|
|
||||||
i = _data.erase(i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!idsChanged.empty()) {
|
auto difference = [&] {
|
||||||
_changed.notify(std::move(idsChanged));
|
WriteLocker lock(this);
|
||||||
|
auto result = CountOptionsDifference(_data, data);
|
||||||
|
if (!result.empty()) {
|
||||||
|
_data = std::move(data);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}();
|
||||||
|
if (!difference.empty()) {
|
||||||
|
_changed.notify(std::move(difference));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -221,23 +194,28 @@ void DcOptions::addFromOther(DcOptions &&options) {
|
|||||||
idsChanged.reserve(options._data.size());
|
idsChanged.reserve(options._data.size());
|
||||||
{
|
{
|
||||||
WriteLocker lock(this);
|
WriteLocker lock(this);
|
||||||
for (const auto &item : base::take(options._data)) {
|
const auto changed = [&](const std::vector<Endpoint> &list) {
|
||||||
for (const auto &option : item.second) {
|
auto result = false;
|
||||||
const auto dcId = option.id;
|
for (const auto &endpoint : list) {
|
||||||
const auto flags = option.flags;
|
const auto dcId = endpoint.id;
|
||||||
const auto &ip = option.ip;
|
const auto flags = endpoint.flags;
|
||||||
const auto port = option.port;
|
const auto &ip = endpoint.ip;
|
||||||
const auto &secret = option.secret;
|
const auto port = endpoint.port;
|
||||||
|
const auto &secret = endpoint.secret;
|
||||||
if (applyOneGuarded(dcId, flags, ip, port, secret)) {
|
if (applyOneGuarded(dcId, flags, ip, port, secret)) {
|
||||||
if (!base::contains(idsChanged, dcId)) {
|
result = true;
|
||||||
idsChanged.push_back(dcId);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return result;
|
||||||
|
};
|
||||||
|
for (const auto &item : base::take(options._data)) {
|
||||||
|
if (changed(item.second)) {
|
||||||
|
idsChanged.push_back(item.first);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
for (auto &keysForDc : options._cdnPublicKeys) {
|
for (auto &item : options._cdnPublicKeys) {
|
||||||
for (auto &entry : keysForDc.second) {
|
for (auto &entry : item.second) {
|
||||||
_cdnPublicKeys[keysForDc.first].insert(std::move(entry));
|
_cdnPublicKeys[item.first].insert(std::move(entry));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -250,7 +228,7 @@ void DcOptions::addFromOther(DcOptions &&options) {
|
|||||||
|
|
||||||
void DcOptions::constructAddOne(
|
void DcOptions::constructAddOne(
|
||||||
int id,
|
int id,
|
||||||
MTPDdcOption::Flags flags,
|
Flags flags,
|
||||||
const std::string &ip,
|
const std::string &ip,
|
||||||
int port,
|
int port,
|
||||||
const bytes::vector &secret) {
|
const bytes::vector &secret) {
|
||||||
@ -260,27 +238,87 @@ void DcOptions::constructAddOne(
|
|||||||
|
|
||||||
bool DcOptions::applyOneGuarded(
|
bool DcOptions::applyOneGuarded(
|
||||||
DcId dcId,
|
DcId dcId,
|
||||||
MTPDdcOption::Flags flags,
|
Flags flags,
|
||||||
const std::string &ip,
|
const std::string &ip,
|
||||||
int port,
|
int port,
|
||||||
const bytes::vector &secret) {
|
const bytes::vector &secret) {
|
||||||
auto dcIdWithShift = MTP::shiftDcId(dcId, flags);
|
return ApplyOneOption(_data, dcId, flags, ip, port, secret);
|
||||||
auto i = _data.find(dcIdWithShift);
|
}
|
||||||
if (i != _data.cend()) {
|
|
||||||
for (auto &option : i->second) {
|
bool DcOptions::ApplyOneOption(
|
||||||
if (option.ip == ip && option.port == port) {
|
std::map<DcId, std::vector<Endpoint>> &data,
|
||||||
|
DcId dcId,
|
||||||
|
Flags flags,
|
||||||
|
const std::string &ip,
|
||||||
|
int port,
|
||||||
|
const bytes::vector &secret) {
|
||||||
|
auto i = data.find(dcId);
|
||||||
|
if (i != data.cend()) {
|
||||||
|
for (auto &endpoint : i->second) {
|
||||||
|
if (endpoint.ip == ip && endpoint.port == port) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
i->second.push_back(Option(dcId, flags, ip, port, secret));
|
i->second.push_back(Endpoint(dcId, flags, ip, port, secret));
|
||||||
} else {
|
} else {
|
||||||
_data.emplace(dcIdWithShift, std::vector<Option>(
|
data.emplace(dcId, std::vector<Endpoint>(
|
||||||
1,
|
1,
|
||||||
Option(dcId, flags, ip, port, secret)));
|
Endpoint(dcId, flags, ip, port, secret)));
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto DcOptions::CountOptionsDifference(
|
||||||
|
const std::map<DcId, std::vector<Endpoint>> &a,
|
||||||
|
const std::map<DcId, std::vector<Endpoint>> &b) -> Ids {
|
||||||
|
auto result = Ids();
|
||||||
|
const auto find = [](
|
||||||
|
const std::vector<Endpoint> &where,
|
||||||
|
const Endpoint &what) {
|
||||||
|
for (const auto &endpoint : where) {
|
||||||
|
if (endpoint.ip == what.ip && endpoint.port == what.port) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
const auto equal = [&](
|
||||||
|
const std::vector<Endpoint> &m,
|
||||||
|
const std::vector<Endpoint> &n) {
|
||||||
|
if (m.size() != n.size()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
for (const auto &endpoint : m) {
|
||||||
|
if (!find(n, endpoint)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
|
auto i = begin(a);
|
||||||
|
auto j = begin(b);
|
||||||
|
const auto max = std::numeric_limits<DcId>::max();
|
||||||
|
while (i != end(a) || j != end(b)) {
|
||||||
|
const auto aId = (i == end(a)) ? max : i->first;
|
||||||
|
const auto bId = (j == end(b)) ? max : j->first;
|
||||||
|
if (aId < bId) {
|
||||||
|
result.push_back(aId);
|
||||||
|
++i;
|
||||||
|
} else if (bId < aId) {
|
||||||
|
result.push_back(bId);
|
||||||
|
++j;
|
||||||
|
} else {
|
||||||
|
if (!equal(i->second, j->second)) {
|
||||||
|
result.push_back(aId);
|
||||||
|
}
|
||||||
|
++i;
|
||||||
|
++j;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
QByteArray DcOptions::serialize() const {
|
QByteArray DcOptions::serialize() const {
|
||||||
if (_immutable) {
|
if (_immutable) {
|
||||||
// Don't write the overriden options to our settings.
|
// Don't write the overriden options to our settings.
|
||||||
@ -298,12 +336,12 @@ QByteArray DcOptions::serialize() const {
|
|||||||
if (isTemporaryDcId(item.first)) {
|
if (isTemporaryDcId(item.first)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
for (const auto &option : item.second) {
|
for (const auto &endpoint : item.second) {
|
||||||
++optionsCount;
|
++optionsCount;
|
||||||
// id + flags + port
|
// id + flags + port
|
||||||
size += sizeof(qint32) + sizeof(qint32) + sizeof(qint32);
|
size += sizeof(qint32) + sizeof(qint32) + sizeof(qint32);
|
||||||
size += sizeof(qint32) + option.ip.size();
|
size += sizeof(qint32) + endpoint.ip.size();
|
||||||
size += sizeof(qint32) + option.secret.size();
|
size += sizeof(qint32) + endpoint.secret.size();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -348,16 +386,16 @@ QByteArray DcOptions::serialize() const {
|
|||||||
if (isTemporaryDcId(item.first)) {
|
if (isTemporaryDcId(item.first)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
for (const auto &option : item.second) {
|
for (const auto &endpoint : item.second) {
|
||||||
stream << qint32(option.id)
|
stream << qint32(endpoint.id)
|
||||||
<< qint32(option.flags)
|
<< qint32(endpoint.flags)
|
||||||
<< qint32(option.port)
|
<< qint32(endpoint.port)
|
||||||
<< qint32(option.ip.size());
|
<< qint32(endpoint.ip.size());
|
||||||
stream.writeRawData(option.ip.data(), option.ip.size());
|
stream.writeRawData(endpoint.ip.data(), endpoint.ip.size());
|
||||||
stream << qint32(option.secret.size());
|
stream << qint32(endpoint.secret.size());
|
||||||
stream.writeRawData(
|
stream.writeRawData(
|
||||||
reinterpret_cast<const char*>(option.secret.data()),
|
reinterpret_cast<const char*>(endpoint.secret.data()),
|
||||||
option.secret.size());
|
endpoint.secret.size());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -404,7 +442,7 @@ void DcOptions::constructFromSerialized(const QByteArray &serialized) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string ip(ipSize, ' ');
|
auto ip = std::string(ipSize, ' ');
|
||||||
stream.readRawData(ip.data(), ipSize);
|
stream.readRawData(ip.data(), ipSize);
|
||||||
|
|
||||||
constexpr auto kMaxSecretSize = 32;
|
constexpr auto kMaxSecretSize = 32;
|
||||||
@ -430,7 +468,7 @@ void DcOptions::constructFromSerialized(const QByteArray &serialized) {
|
|||||||
|
|
||||||
applyOneGuarded(
|
applyOneGuarded(
|
||||||
DcId(id),
|
DcId(id),
|
||||||
MTPDdcOption::Flags::from_raw(flags),
|
Flags::from_raw(flags),
|
||||||
ip,
|
ip,
|
||||||
port,
|
port,
|
||||||
secret);
|
secret);
|
||||||
@ -470,11 +508,10 @@ DcOptions::Ids DcOptions::configEnumDcIds() const {
|
|||||||
ReadLocker lock(this);
|
ReadLocker lock(this);
|
||||||
result.reserve(_data.size());
|
result.reserve(_data.size());
|
||||||
for (auto &item : _data) {
|
for (auto &item : _data) {
|
||||||
const auto dcId = bareDcId(item.first);
|
const auto dcId = item.first;
|
||||||
Assert(!item.second.empty());
|
Assert(!item.second.empty());
|
||||||
if (!isCdnDc(item.second.front().flags)
|
if (!isCdnDc(item.second.front().flags)
|
||||||
&& !isTemporaryDcId(item.first)
|
&& !isTemporaryDcId(dcId)) {
|
||||||
&& !base::contains(result, dcId)) {
|
|
||||||
result.push_back(dcId);
|
result.push_back(dcId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -542,186 +579,72 @@ bool DcOptions::getDcRSAKey(DcId dcId, const QVector<MTPlong> &fingerprints, int
|
|||||||
return findKey(_publicKeys);
|
return findKey(_publicKeys);
|
||||||
}
|
}
|
||||||
|
|
||||||
DcOptions::Variants DcOptions::lookup(
|
auto DcOptions::lookup(
|
||||||
DcId dcId,
|
DcId dcId,
|
||||||
DcType type,
|
DcType type,
|
||||||
bool throughProxy) const {
|
bool throughProxy) const -> Variants {
|
||||||
auto lookupDesiredFlags = [&](int address, int protocol) -> std::vector<MTPDdcOption::Flags> {
|
using Flag = Flag;
|
||||||
switch (type) {
|
|
||||||
case DcType::Regular:
|
|
||||||
case DcType::Temporary: {
|
|
||||||
switch (address) {
|
|
||||||
case Variants::IPv4: {
|
|
||||||
switch (protocol) {
|
|
||||||
case Variants::Tcp: return {
|
|
||||||
// Regular TCP IPv4
|
|
||||||
throughProxy ? (MTPDdcOption::Flag::f_secret | MTPDdcOption::Flag::f_tcpo_only | MTPDdcOption::Flag::f_static) : (MTPDdcOption::Flag::f_secret | MTPDdcOption::Flag::f_tcpo_only),
|
|
||||||
throughProxy ? (MTPDdcOption::Flag::f_tcpo_only | MTPDdcOption::Flag::f_static) : (MTPDdcOption::Flag::f_tcpo_only | 0),
|
|
||||||
throughProxy ? (MTPDdcOption::Flag::f_static | 0) : MTPDdcOption::Flags(0),
|
|
||||||
(MTPDdcOption::Flag::f_secret | MTPDdcOption::Flag::f_tcpo_only),
|
|
||||||
(MTPDdcOption::Flag::f_tcpo_only | 0),
|
|
||||||
0
|
|
||||||
};
|
|
||||||
case Variants::Http: return {
|
|
||||||
// Regular HTTP IPv4
|
|
||||||
throughProxy ? (MTPDdcOption::Flag::f_static | 0) : MTPDdcOption::Flags(0),
|
|
||||||
0,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
} break;
|
|
||||||
case Variants::IPv6: {
|
|
||||||
switch (protocol) {
|
|
||||||
case Variants::Tcp: return {
|
|
||||||
// Regular TCP IPv6
|
|
||||||
throughProxy ? (MTPDdcOption::Flag::f_secret | MTPDdcOption::Flag::f_tcpo_only | MTPDdcOption::Flag::f_ipv6 | MTPDdcOption::Flag::f_static) : (MTPDdcOption::Flag::f_secret | MTPDdcOption::Flag::f_tcpo_only | MTPDdcOption::Flag::f_ipv6),
|
|
||||||
throughProxy ? (MTPDdcOption::Flag::f_tcpo_only | MTPDdcOption::Flag::f_ipv6 | MTPDdcOption::Flag::f_static) : (MTPDdcOption::Flag::f_tcpo_only | MTPDdcOption::Flag::f_ipv6),
|
|
||||||
throughProxy ? (MTPDdcOption::Flag::f_ipv6 | MTPDdcOption::Flag::f_static) : (MTPDdcOption::Flag::f_ipv6 | 0),
|
|
||||||
(MTPDdcOption::Flag::f_secret | MTPDdcOption::Flag::f_tcpo_only | MTPDdcOption::Flag::f_ipv6),
|
|
||||||
(MTPDdcOption::Flag::f_tcpo_only | MTPDdcOption::Flag::f_ipv6),
|
|
||||||
(MTPDdcOption::Flag::f_ipv6 | 0),
|
|
||||||
};
|
|
||||||
case Variants::Http: return {
|
|
||||||
// Regular HTTP IPv6
|
|
||||||
throughProxy ? (MTPDdcOption::Flag::f_ipv6 | MTPDdcOption::Flag::f_static) : (MTPDdcOption::Flag::f_ipv6 | 0),
|
|
||||||
(MTPDdcOption::Flag::f_ipv6 | 0),
|
|
||||||
};
|
|
||||||
}
|
|
||||||
} break;
|
|
||||||
}
|
|
||||||
} break;
|
|
||||||
case DcType::MediaDownload: {
|
|
||||||
switch (address) {
|
|
||||||
case Variants::IPv4: {
|
|
||||||
switch (protocol) {
|
|
||||||
case Variants::Tcp: return {
|
|
||||||
// Media download TCP IPv4
|
|
||||||
throughProxy ? (MTPDdcOption::Flag::f_media_only | MTPDdcOption::Flag::f_secret | MTPDdcOption::Flag::f_tcpo_only | MTPDdcOption::Flag::f_static) : (MTPDdcOption::Flag::f_media_only | MTPDdcOption::Flag::f_secret | MTPDdcOption::Flag::f_tcpo_only),
|
|
||||||
throughProxy ? (MTPDdcOption::Flag::f_media_only | MTPDdcOption::Flag::f_tcpo_only | MTPDdcOption::Flag::f_static) : (MTPDdcOption::Flag::f_media_only | MTPDdcOption::Flag::f_tcpo_only),
|
|
||||||
throughProxy ? (MTPDdcOption::Flag::f_media_only | MTPDdcOption::Flag::f_static) : (MTPDdcOption::Flag::f_secret | MTPDdcOption::Flag::f_tcpo_only),
|
|
||||||
throughProxy ? (MTPDdcOption::Flag::f_media_only | MTPDdcOption::Flag::f_static) : (MTPDdcOption::Flag::f_tcpo_only | 0),
|
|
||||||
(MTPDdcOption::Flag::f_media_only | 0),
|
|
||||||
throughProxy ? (MTPDdcOption::Flag::f_static | 0) : MTPDdcOption::Flags(0),
|
|
||||||
(MTPDdcOption::Flag::f_media_only | MTPDdcOption::Flag::f_secret | MTPDdcOption::Flag::f_tcpo_only),
|
|
||||||
(MTPDdcOption::Flag::f_media_only | MTPDdcOption::Flag::f_tcpo_only),
|
|
||||||
throughProxy ? (MTPDdcOption::Flag::f_secret | MTPDdcOption::Flag::f_tcpo_only | MTPDdcOption::Flag::f_static) : (MTPDdcOption::Flag::f_secret | MTPDdcOption::Flag::f_tcpo_only),
|
|
||||||
throughProxy ? (MTPDdcOption::Flag::f_tcpo_only | MTPDdcOption::Flag::f_static) : (MTPDdcOption::Flag::f_tcpo_only | 0),
|
|
||||||
throughProxy ? (MTPDdcOption::Flag::f_secret | MTPDdcOption::Flag::f_tcpo_only) : (MTPDdcOption::Flag::f_media_only | 0),
|
|
||||||
throughProxy ? (MTPDdcOption::Flag::f_tcpo_only | 0) : (MTPDdcOption::Flag::f_media_only | 0),
|
|
||||||
0,
|
|
||||||
};
|
|
||||||
case Variants::Http: return {
|
|
||||||
// Media download HTTP IPv4
|
|
||||||
throughProxy ? (MTPDdcOption::Flag::f_media_only | MTPDdcOption::Flag::f_static) : (MTPDdcOption::Flag::f_media_only | 0),
|
|
||||||
(MTPDdcOption::Flag::f_media_only | 0),
|
|
||||||
throughProxy ? (MTPDdcOption::Flag::f_static | 0) : MTPDdcOption::Flags(0),
|
|
||||||
0,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
} break;
|
|
||||||
case Variants::IPv6: {
|
|
||||||
switch (protocol) {
|
|
||||||
case Variants::Tcp: return {
|
|
||||||
// Media download TCP IPv6
|
|
||||||
throughProxy ? (MTPDdcOption::Flag::f_media_only | MTPDdcOption::Flag::f_secret | MTPDdcOption::Flag::f_tcpo_only | MTPDdcOption::Flag::f_ipv6 | MTPDdcOption::Flag::f_static) : (MTPDdcOption::Flag::f_media_only | MTPDdcOption::Flag::f_secret | MTPDdcOption::Flag::f_tcpo_only | MTPDdcOption::Flag::f_ipv6),
|
|
||||||
throughProxy ? (MTPDdcOption::Flag::f_media_only | MTPDdcOption::Flag::f_tcpo_only | MTPDdcOption::Flag::f_ipv6 | MTPDdcOption::Flag::f_static) : (MTPDdcOption::Flag::f_media_only | MTPDdcOption::Flag::f_tcpo_only | MTPDdcOption::Flag::f_ipv6),
|
|
||||||
throughProxy ? (MTPDdcOption::Flag::f_media_only | MTPDdcOption::Flag::f_ipv6 | MTPDdcOption::Flag::f_static) : (MTPDdcOption::Flag::f_secret | MTPDdcOption::Flag::f_tcpo_only | MTPDdcOption::Flag::f_ipv6),
|
|
||||||
throughProxy ? (MTPDdcOption::Flag::f_media_only | MTPDdcOption::Flag::f_ipv6 | MTPDdcOption::Flag::f_static) : (MTPDdcOption::Flag::f_tcpo_only | MTPDdcOption::Flag::f_ipv6),
|
|
||||||
(MTPDdcOption::Flag::f_media_only | MTPDdcOption::Flag::f_ipv6),
|
|
||||||
throughProxy ? (MTPDdcOption::Flag::f_ipv6 | MTPDdcOption::Flag::f_static) : (MTPDdcOption::Flag::f_ipv6 | 0),
|
|
||||||
(MTPDdcOption::Flag::f_media_only | MTPDdcOption::Flag::f_secret | MTPDdcOption::Flag::f_tcpo_only | MTPDdcOption::Flag::f_ipv6),
|
|
||||||
(MTPDdcOption::Flag::f_media_only | MTPDdcOption::Flag::f_tcpo_only | MTPDdcOption::Flag::f_ipv6),
|
|
||||||
throughProxy ? (MTPDdcOption::Flag::f_secret | MTPDdcOption::Flag::f_tcpo_only | MTPDdcOption::Flag::f_ipv6 | MTPDdcOption::Flag::f_static) : (MTPDdcOption::Flag::f_secret | MTPDdcOption::Flag::f_tcpo_only | MTPDdcOption::Flag::f_ipv6),
|
|
||||||
throughProxy ? (MTPDdcOption::Flag::f_tcpo_only | MTPDdcOption::Flag::f_ipv6 | MTPDdcOption::Flag::f_static) : (MTPDdcOption::Flag::f_tcpo_only | MTPDdcOption::Flag::f_ipv6),
|
|
||||||
throughProxy ? (MTPDdcOption::Flag::f_secret | MTPDdcOption::Flag::f_tcpo_only | MTPDdcOption::Flag::f_ipv6) : (MTPDdcOption::Flag::f_media_only | MTPDdcOption::Flag::f_ipv6),
|
|
||||||
throughProxy ? (MTPDdcOption::Flag::f_tcpo_only | MTPDdcOption::Flag::f_ipv6) : (MTPDdcOption::Flag::f_media_only | MTPDdcOption::Flag::f_ipv6),
|
|
||||||
(MTPDdcOption::Flag::f_ipv6 | 0)
|
|
||||||
};
|
|
||||||
case Variants::Http: return {
|
|
||||||
// Media download HTTP IPv6
|
|
||||||
throughProxy ? (MTPDdcOption::Flag::f_media_only | MTPDdcOption::Flag::f_ipv6 | MTPDdcOption::Flag::f_static) : (MTPDdcOption::Flag::f_media_only | MTPDdcOption::Flag::f_ipv6),
|
|
||||||
(MTPDdcOption::Flag::f_media_only | MTPDdcOption::Flag::f_ipv6),
|
|
||||||
throughProxy ? (MTPDdcOption::Flag::f_ipv6 | MTPDdcOption::Flag::f_static) : (MTPDdcOption::Flag::f_ipv6 | 0),
|
|
||||||
(MTPDdcOption::Flag::f_ipv6 | 0),
|
|
||||||
};
|
|
||||||
}
|
|
||||||
} break;
|
|
||||||
}
|
|
||||||
} break;
|
|
||||||
case DcType::Cdn: {
|
|
||||||
switch (address) {
|
|
||||||
case Variants::IPv4: {
|
|
||||||
switch (protocol) {
|
|
||||||
case Variants::Tcp: return {
|
|
||||||
// CDN TCP IPv4
|
|
||||||
throughProxy ? (MTPDdcOption::Flag::f_cdn | MTPDdcOption::Flag::f_secret | MTPDdcOption::Flag::f_tcpo_only | MTPDdcOption::Flag::f_static) : (MTPDdcOption::Flag::f_cdn | MTPDdcOption::Flag::f_secret | MTPDdcOption::Flag::f_tcpo_only),
|
|
||||||
throughProxy ? (MTPDdcOption::Flag::f_cdn | MTPDdcOption::Flag::f_tcpo_only | MTPDdcOption::Flag::f_static) : (MTPDdcOption::Flag::f_cdn | MTPDdcOption::Flag::f_tcpo_only),
|
|
||||||
throughProxy ? (MTPDdcOption::Flag::f_cdn | MTPDdcOption::Flag::f_static) : (MTPDdcOption::Flag::f_cdn | 0),
|
|
||||||
(MTPDdcOption::Flag::f_cdn | MTPDdcOption::Flag::f_secret | MTPDdcOption::Flag::f_tcpo_only),
|
|
||||||
(MTPDdcOption::Flag::f_cdn | MTPDdcOption::Flag::f_tcpo_only),
|
|
||||||
(MTPDdcOption::Flag::f_cdn | 0),
|
|
||||||
};
|
|
||||||
case Variants::Http: return {
|
|
||||||
// CDN HTTP IPv4
|
|
||||||
throughProxy ? (MTPDdcOption::Flag::f_cdn | MTPDdcOption::Flag::f_static) : (MTPDdcOption::Flag::f_cdn | 0),
|
|
||||||
(MTPDdcOption::Flag::f_cdn | 0),
|
|
||||||
};
|
|
||||||
}
|
|
||||||
} break;
|
|
||||||
case Variants::IPv6: {
|
|
||||||
switch (protocol) {
|
|
||||||
case Variants::Tcp: return {
|
|
||||||
// CDN TCP IPv6
|
|
||||||
throughProxy ? (MTPDdcOption::Flag::f_cdn | MTPDdcOption::Flag::f_ipv6 | MTPDdcOption::Flag::f_secret | MTPDdcOption::Flag::f_tcpo_only | MTPDdcOption::Flag::f_static) : (MTPDdcOption::Flag::f_cdn | MTPDdcOption::Flag::f_ipv6 | MTPDdcOption::Flag::f_secret | MTPDdcOption::Flag::f_tcpo_only),
|
|
||||||
throughProxy ? (MTPDdcOption::Flag::f_cdn | MTPDdcOption::Flag::f_ipv6 | MTPDdcOption::Flag::f_tcpo_only | MTPDdcOption::Flag::f_static) : (MTPDdcOption::Flag::f_cdn | MTPDdcOption::Flag::f_ipv6 | MTPDdcOption::Flag::f_tcpo_only),
|
|
||||||
throughProxy ? (MTPDdcOption::Flag::f_cdn | MTPDdcOption::Flag::f_ipv6 | MTPDdcOption::Flag::f_static) : (MTPDdcOption::Flag::f_cdn | MTPDdcOption::Flag::f_ipv6),
|
|
||||||
(MTPDdcOption::Flag::f_cdn | MTPDdcOption::Flag::f_secret | MTPDdcOption::Flag::f_tcpo_only | MTPDdcOption::Flag::f_ipv6),
|
|
||||||
(MTPDdcOption::Flag::f_cdn | MTPDdcOption::Flag::f_tcpo_only | MTPDdcOption::Flag::f_ipv6),
|
|
||||||
(MTPDdcOption::Flag::f_cdn | MTPDdcOption::Flag::f_ipv6),
|
|
||||||
};
|
|
||||||
case Variants::Http: return {
|
|
||||||
// CDN HTTP IPv6
|
|
||||||
throughProxy ? (MTPDdcOption::Flag::f_cdn | MTPDdcOption::Flag::f_ipv6 | MTPDdcOption::Flag::f_static) : (MTPDdcOption::Flag::f_cdn | MTPDdcOption::Flag::f_ipv6),
|
|
||||||
(MTPDdcOption::Flag::f_cdn | MTPDdcOption::Flag::f_ipv6),
|
|
||||||
};
|
|
||||||
}
|
|
||||||
} break;
|
|
||||||
}
|
|
||||||
} break;
|
|
||||||
}
|
|
||||||
Unexpected("Bad type / address / protocol");
|
|
||||||
};
|
|
||||||
|
|
||||||
auto result = Variants();
|
auto result = Variants();
|
||||||
{
|
{
|
||||||
ReadLocker lock(this);
|
ReadLocker lock(this);
|
||||||
for (auto address = 0; address != Variants::AddressTypeCount; ++address) {
|
const auto i = _data.find(dcId);
|
||||||
for (auto protocol = 0; protocol != Variants::ProtocolCount; ++protocol) {
|
if (i == end(_data)) {
|
||||||
auto desiredFlags = lookupDesiredFlags(address, protocol);
|
return result;
|
||||||
for (auto flags : desiredFlags) {
|
}
|
||||||
const auto shift = static_cast<int>(flags);
|
for (const auto &endpoint : i->second) {
|
||||||
const auto it = _data.find(shiftDcId(dcId, shift));
|
const auto flags = endpoint.flags;
|
||||||
if (it != _data.cend()) {
|
if (type == DcType::Cdn && !(flags & Flag::f_cdn)) {
|
||||||
for (const auto &option : it->second) {
|
continue;
|
||||||
result.data[address][protocol].push_back({
|
} else if (throughProxy && !(flags & Flag::f_static)) {
|
||||||
option.ip,
|
continue;
|
||||||
option.port,
|
|
||||||
option.secret
|
|
||||||
});
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
if (type != DcType::MediaDownload
|
||||||
|
&& (flags & Flag::f_media_only)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
const auto address = (flags & Flag::f_ipv6)
|
||||||
|
? Variants::IPv6
|
||||||
|
: Variants::IPv4;
|
||||||
|
result.data[address][Variants::Tcp].push_back(endpoint);
|
||||||
|
if (!(flags & (Flag::f_tcpo_only | Flag::f_secret))) {
|
||||||
|
result.data[address][Variants::Http].push_back(endpoint);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (type == DcType::MediaDownload) {
|
||||||
|
FilterIfHasWithFlag(result, Flag::f_media_only);
|
||||||
|
}
|
||||||
|
if (throughProxy) {
|
||||||
|
FilterIfHasWithFlag(result, Flag::f_static);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DcOptions::FilterIfHasWithFlag(Variants &variants, Flag flag) {
|
||||||
|
const auto is = [&](const Endpoint &endpoint) {
|
||||||
|
return (endpoint.flags & flag) != 0;
|
||||||
|
};
|
||||||
|
const auto has = [&](const std::vector<Endpoint> &list) {
|
||||||
|
return ranges::find_if(list, is) != end(list);
|
||||||
|
};
|
||||||
|
for (auto &byAddress : variants.data) {
|
||||||
|
for (auto &list : byAddress) {
|
||||||
|
if (has(list)) {
|
||||||
|
list = ranges::view::all(
|
||||||
|
list
|
||||||
|
) | ranges::view::filter(
|
||||||
|
is
|
||||||
|
) | ranges::to_vector;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void DcOptions::computeCdnDcIds() {
|
void DcOptions::computeCdnDcIds() {
|
||||||
_cdnDcIds.clear();
|
_cdnDcIds.clear();
|
||||||
for (auto &item : _data) {
|
for (auto &item : _data) {
|
||||||
Assert(!item.second.empty());
|
Assert(!item.second.empty());
|
||||||
if (item.second.front().flags & MTPDdcOption::Flag::f_cdn) {
|
if (item.second.front().flags & Flag::f_cdn) {
|
||||||
_cdnDcIds.insert(bareDcId(item.first));
|
_cdnDcIds.insert(bareDcId(item.first));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -758,17 +681,17 @@ bool DcOptions::loadFromFile(const QString &path) {
|
|||||||
if (dcId <= 0 || dcId >= internal::kDcShift || !host.setAddress(ip) || port <= 0) {
|
if (dcId <= 0 || dcId >= internal::kDcShift || !host.setAddress(ip) || port <= 0) {
|
||||||
return error();
|
return error();
|
||||||
}
|
}
|
||||||
auto flags = MTPDdcOption::Flags(0);
|
auto flags = Flags(0);
|
||||||
if (host.protocol() == QAbstractSocket::IPv6Protocol) {
|
if (host.protocol() == QAbstractSocket::IPv6Protocol) {
|
||||||
flags |= MTPDdcOption::Flag::f_ipv6;
|
flags |= Flag::f_ipv6;
|
||||||
}
|
}
|
||||||
for (auto &option : components.mid(3)) {
|
for (auto &option : components.mid(3)) {
|
||||||
if (option.startsWith('#')) {
|
if (option.startsWith('#')) {
|
||||||
break;
|
break;
|
||||||
} else if (option == qstr("tcpo_only")) {
|
} else if (option == qstr("tcpo_only")) {
|
||||||
flags |= MTPDdcOption::Flag::f_tcpo_only;
|
flags |= Flag::f_tcpo_only;
|
||||||
} else if (option == qstr("media_only")) {
|
} else if (option == qstr("media_only")) {
|
||||||
flags |= MTPDdcOption::Flag::f_media_only;
|
flags |= Flag::f_media_only;
|
||||||
} else {
|
} else {
|
||||||
return error();
|
return error();
|
||||||
}
|
}
|
||||||
@ -808,10 +731,10 @@ bool DcOptions::writeToFile(const QString &path) const {
|
|||||||
<< ' '
|
<< ' '
|
||||||
<< QString::fromStdString(option.ip)
|
<< QString::fromStdString(option.ip)
|
||||||
<< ' ' << option.port;
|
<< ' ' << option.port;
|
||||||
if (option.flags & MTPDdcOption::Flag::f_tcpo_only) {
|
if (option.flags & Flag::f_tcpo_only) {
|
||||||
stream << " tcpo_only";
|
stream << " tcpo_only";
|
||||||
}
|
}
|
||||||
if (option.flags & MTPDdcOption::Flag::f_media_only) {
|
if (option.flags & Flag::f_media_only) {
|
||||||
stream << " media_only";
|
stream << " media_only";
|
||||||
}
|
}
|
||||||
stream << '\n';
|
stream << '\n';
|
||||||
|
@ -24,12 +24,36 @@ enum class DcType {
|
|||||||
};
|
};
|
||||||
class DcOptions {
|
class DcOptions {
|
||||||
public:
|
public:
|
||||||
|
using Flag = MTPDdcOption::Flag;
|
||||||
|
using Flags = MTPDdcOption::Flags;
|
||||||
|
struct Endpoint {
|
||||||
|
Endpoint(
|
||||||
|
DcId id,
|
||||||
|
Flags flags,
|
||||||
|
const std::string &ip,
|
||||||
|
int port,
|
||||||
|
const bytes::vector &secret)
|
||||||
|
: id(id)
|
||||||
|
, flags(flags)
|
||||||
|
, ip(ip)
|
||||||
|
, port(port)
|
||||||
|
, secret(secret) {
|
||||||
|
}
|
||||||
|
|
||||||
|
DcId id;
|
||||||
|
Flags flags;
|
||||||
|
std::string ip;
|
||||||
|
int port;
|
||||||
|
bytes::vector secret;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
// construct methods don't notify "changed" subscribers.
|
// construct methods don't notify "changed" subscribers.
|
||||||
void constructFromSerialized(const QByteArray &serialized);
|
void constructFromSerialized(const QByteArray &serialized);
|
||||||
void constructFromBuiltIn();
|
void constructFromBuiltIn();
|
||||||
void constructAddOne(
|
void constructAddOne(
|
||||||
int id,
|
int id,
|
||||||
MTPDdcOption::Flags flags,
|
Flags flags,
|
||||||
const std::string &ip,
|
const std::string &ip,
|
||||||
int port,
|
int port,
|
||||||
const bytes::vector &secret);
|
const bytes::vector &secret);
|
||||||
@ -45,11 +69,6 @@ public:
|
|||||||
|
|
||||||
Ids configEnumDcIds() const;
|
Ids configEnumDcIds() const;
|
||||||
|
|
||||||
struct Endpoint {
|
|
||||||
std::string ip;
|
|
||||||
int port = 0;
|
|
||||||
bytes::vector protocolSecret;
|
|
||||||
};
|
|
||||||
struct Variants {
|
struct Variants {
|
||||||
enum Address {
|
enum Address {
|
||||||
IPv4 = 0,
|
IPv4 = 0,
|
||||||
@ -75,33 +94,23 @@ public:
|
|||||||
bool writeToFile(const QString &path) const;
|
bool writeToFile(const QString &path) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct Option {
|
|
||||||
Option(
|
|
||||||
DcId id,
|
|
||||||
MTPDdcOption::Flags flags,
|
|
||||||
const std::string &ip,
|
|
||||||
int port,
|
|
||||||
const bytes::vector &secret)
|
|
||||||
: id(id)
|
|
||||||
, flags(flags)
|
|
||||||
, ip(ip)
|
|
||||||
, port(port)
|
|
||||||
, secret(secret) {
|
|
||||||
}
|
|
||||||
|
|
||||||
DcId id;
|
|
||||||
MTPDdcOption::Flags flags;
|
|
||||||
std::string ip;
|
|
||||||
int port;
|
|
||||||
bytes::vector secret;
|
|
||||||
|
|
||||||
};
|
|
||||||
bool applyOneGuarded(
|
bool applyOneGuarded(
|
||||||
DcId dcId,
|
DcId dcId,
|
||||||
MTPDdcOption::Flags flags,
|
Flags flags,
|
||||||
const std::string &ip,
|
const std::string &ip,
|
||||||
int port,
|
int port,
|
||||||
const bytes::vector &secret);
|
const bytes::vector &secret);
|
||||||
|
static bool ApplyOneOption(
|
||||||
|
std::map<DcId, std::vector<Endpoint>> &data,
|
||||||
|
DcId dcId,
|
||||||
|
Flags flags,
|
||||||
|
const std::string &ip,
|
||||||
|
int port,
|
||||||
|
const bytes::vector &secret);
|
||||||
|
static Ids CountOptionsDifference(
|
||||||
|
const std::map<DcId, std::vector<Endpoint>> &a,
|
||||||
|
const std::map<DcId, std::vector<Endpoint>> &b);
|
||||||
|
static void FilterIfHasWithFlag(Variants &variants, Flag flag);
|
||||||
|
|
||||||
void processFromList(const QVector<MTPDcOption> &options, bool overwrite);
|
void processFromList(const QVector<MTPDcOption> &options, bool overwrite);
|
||||||
void computeCdnDcIds();
|
void computeCdnDcIds();
|
||||||
@ -114,7 +123,7 @@ private:
|
|||||||
class ReadLocker;
|
class ReadLocker;
|
||||||
friend class ReadLocker;
|
friend class ReadLocker;
|
||||||
|
|
||||||
std::map<ShiftedDcId, std::vector<Option>> _data;
|
std::map<DcId, std::vector<Endpoint>> _data;
|
||||||
std::set<DcId> _cdnDcIds;
|
std::set<DcId> _cdnDcIds;
|
||||||
std::map<uint64, internal::RSAPublicKey> _publicKeys;
|
std::map<uint64, internal::RSAPublicKey> _publicKeys;
|
||||||
std::map<DcId, std::map<uint64, internal::RSAPublicKey>> _cdnPublicKeys;
|
std::map<DcId, std::map<uint64, internal::RSAPublicKey>> _cdnPublicKeys;
|
||||||
|
Loading…
Reference in New Issue
Block a user