Update API scheme to layer 78.

This commit is contained in:
John Preston 2018-04-25 13:24:48 +04:00
parent 93f6d4b6e7
commit 65f968ec1b
10 changed files with 194 additions and 80 deletions

View File

@ -220,7 +220,7 @@ userStatusLastMonth#77ebc742 = UserStatus;
chatEmpty#9ba2d800 id:int = Chat; chatEmpty#9ba2d800 id:int = Chat;
chat#d91cdd54 flags:# creator:flags.0?true kicked:flags.1?true left:flags.2?true admins_enabled:flags.3?true admin:flags.4?true deactivated:flags.5?true id:int title:string photo:ChatPhoto participants_count:int date:int version:int migrated_to:flags.6?InputChannel = Chat; chat#d91cdd54 flags:# creator:flags.0?true kicked:flags.1?true left:flags.2?true admins_enabled:flags.3?true admin:flags.4?true deactivated:flags.5?true id:int title:string photo:ChatPhoto participants_count:int date:int version:int migrated_to:flags.6?InputChannel = Chat;
chatForbidden#7328bdb id:int title:string = Chat; chatForbidden#7328bdb id:int title:string = Chat;
channel#450b7115 flags:# creator:flags.0?true left:flags.2?true editor:flags.3?true broadcast:flags.5?true verified:flags.7?true megagroup:flags.8?true restricted:flags.9?true democracy:flags.10?true signatures:flags.11?true min:flags.12?true id:int access_hash:flags.13?long title:string username:flags.6?string photo:ChatPhoto date:int version:int restriction_reason:flags.9?string admin_rights:flags.14?ChannelAdminRights banned_rights:flags.15?ChannelBannedRights participants_count:flags.17?int = Chat; channel#c88974ac flags:# creator:flags.0?true left:flags.2?true editor:flags.3?true broadcast:flags.5?true verified:flags.7?true megagroup:flags.8?true restricted:flags.9?true democracy:flags.10?true signatures:flags.11?true min:flags.12?true id:int access_hash:flags.13?long title:string username:flags.6?string photo:ChatPhoto date:int version:int restriction_reason:flags.9?string admin_rights:flags.14?ChannelAdminRights banned_rights:flags.15?ChannelBannedRights participants_count:flags.17?int = Chat;
channelForbidden#289da732 flags:# broadcast:flags.5?true megagroup:flags.8?true id:int access_hash:long title:string until_date:flags.16?int = Chat; channelForbidden#289da732 flags:# broadcast:flags.5?true megagroup:flags.8?true id:int access_hash:long title:string until_date:flags.16?int = Chat;
chatFull#2e02a614 id:int participants:ChatParticipants chat_photo:Photo notify_settings:PeerNotifySettings exported_invite:ExportedChatInvite bot_info:Vector<BotInfo> = ChatFull; chatFull#2e02a614 id:int participants:ChatParticipants chat_photo:Photo notify_settings:PeerNotifySettings exported_invite:ExportedChatInvite bot_info:Vector<BotInfo> = ChatFull;
@ -306,7 +306,6 @@ inputPeerNotifySettings#38935eb2 flags:# show_previews:flags.0?true silent:flags
peerNotifyEventsEmpty#add53cb3 = PeerNotifyEvents; peerNotifyEventsEmpty#add53cb3 = PeerNotifyEvents;
peerNotifyEventsAll#6d1ded88 = PeerNotifyEvents; peerNotifyEventsAll#6d1ded88 = PeerNotifyEvents;
peerNotifySettingsEmpty#70a68512 = PeerNotifySettings;
peerNotifySettings#9acda4c0 flags:# show_previews:flags.0?true silent:flags.1?true mute_until:int sound:string = PeerNotifySettings; peerNotifySettings#9acda4c0 flags:# show_previews:flags.0?true silent:flags.1?true mute_until:int sound:string = PeerNotifySettings;
peerSettings#818426cd flags:# report_spam:flags.0?true = PeerSettings; peerSettings#818426cd flags:# report_spam:flags.0?true = PeerSettings;
@ -461,7 +460,7 @@ photos.photo#20212ca8 photo:Photo users:Vector<User> = photos.Photo;
upload.file#96a18d5 type:storage.FileType mtime:int bytes:bytes = upload.File; upload.file#96a18d5 type:storage.FileType mtime:int bytes:bytes = upload.File;
upload.fileCdnRedirect#f18cda44 dc_id:int file_token:bytes encryption_key:bytes encryption_iv:bytes file_hashes:Vector<FileHash> = upload.File; upload.fileCdnRedirect#f18cda44 dc_id:int file_token:bytes encryption_key:bytes encryption_iv:bytes file_hashes:Vector<FileHash> = upload.File;
dcOption#5d8c6cc flags:# ipv6:flags.0?true media_only:flags.1?true tcpo_only:flags.2?true cdn:flags.3?true static:flags.4?true id:int ip_address:string port:int = DcOption; dcOption#18b7a10d flags:# ipv6:flags.0?true media_only:flags.1?true tcpo_only:flags.2?true cdn:flags.3?true static:flags.4?true id:int ip_address:string port:int secret:flags.10?bytes = DcOption;
config#86b5778e flags:# phonecalls_enabled:flags.1?true default_p2p_contacts:flags.3?true preload_featured_stickers:flags.4?true ignore_phone_entities:flags.5?true revoke_pm_inbox:flags.6?true date:int expires:int test_mode:Bool this_dc:int dc_options:Vector<DcOption> chat_size_max:int megagroup_size_max:int forwarded_count_max:int online_update_period_ms:int offline_blur_timeout_ms:int offline_idle_timeout_ms:int online_cloud_timeout_ms:int notify_cloud_delay_ms:int notify_default_delay_ms:int push_chat_period_ms:int push_chat_limit:int saved_gifs_limit:int edit_time_limit:int revoke_time_limit:int revoke_pm_time_limit:int rating_e_decay:int stickers_recent_limit:int stickers_faved_limit:int channels_read_media_period:int tmp_sessions:flags.0?int pinned_dialogs_count_max:int call_receive_timeout_ms:int call_ring_timeout_ms:int call_connect_timeout_ms:int call_packet_timeout_ms:int me_url_prefix:string suggested_lang_code:flags.2?string lang_pack_version:flags.2?int = Config; config#86b5778e flags:# phonecalls_enabled:flags.1?true default_p2p_contacts:flags.3?true preload_featured_stickers:flags.4?true ignore_phone_entities:flags.5?true revoke_pm_inbox:flags.6?true date:int expires:int test_mode:Bool this_dc:int dc_options:Vector<DcOption> chat_size_max:int megagroup_size_max:int forwarded_count_max:int online_update_period_ms:int offline_blur_timeout_ms:int offline_idle_timeout_ms:int online_cloud_timeout_ms:int notify_cloud_delay_ms:int notify_default_delay_ms:int push_chat_period_ms:int push_chat_limit:int saved_gifs_limit:int edit_time_limit:int revoke_time_limit:int revoke_pm_time_limit:int rating_e_decay:int stickers_recent_limit:int stickers_faved_limit:int channels_read_media_period:int tmp_sessions:flags.0?int pinned_dialogs_count_max:int call_receive_timeout_ms:int call_ring_timeout_ms:int call_connect_timeout_ms:int call_packet_timeout_ms:int me_url_prefix:string suggested_lang_code:flags.2?string lang_pack_version:flags.2?int = Config;
@ -1220,4 +1219,4 @@ langpack.getStrings#2e1ee318 lang_code:string keys:Vector<string> = Vector<LangP
langpack.getDifference#b2e4d7d from_version:int = LangPackDifference; langpack.getDifference#b2e4d7d from_version:int = LangPackDifference;
langpack.getLanguages#800fd57d = Vector<LangPackLanguage>; langpack.getLanguages#800fd57d = Vector<LangPackLanguage>;
// LAYER 76 // LAYER 78

View File

@ -1623,7 +1623,10 @@ void ApiWrap::requestNotifySetting(PeerData *peer) {
notifySettingReceived(notifyPeer, result); notifySettingReceived(notifyPeer, result);
_notifySettingRequests.remove(peer); _notifySettingRequests.remove(peer);
}).fail([this, notifyPeer, peer](const RPCError &error) { }).fail([this, notifyPeer, peer](const RPCError &error) {
notifySettingReceived(notifyPeer, MTP_peerNotifySettingsEmpty()); notifySettingReceived(notifyPeer, MTP_peerNotifySettings(
MTP_flags(MTPDpeerNotifySettings::Flag::f_show_previews),
MTP_int(0),
MTP_string("default")));
_notifySettingRequests.remove(peer); _notifySettingRequests.remove(peer);
}).send(); }).send();

View File

@ -54,7 +54,13 @@ addChildParentFlags('MTPDchannelForbidden', 'MTPDchannel');
# each key flag of parentFlags should be a subset of the value flag here # each key flag of parentFlags should be a subset of the value flag here
parentFlagsCheck = {}; parentFlagsCheck = {};
countedTypeIdExceptions = {};
countedTypeIdExceptions[77] = countedTypeIdExceptions[78] = {}
countedTypeIdExceptions[77]['channel'] = countedTypeIdExceptions[78]['channel'] = True
lines = [];
layer = ''; layer = '';
layerIndex = 0;
funcs = 0 funcs = 0
types = 0; types = 0;
consts = 0 consts = 0
@ -83,7 +89,12 @@ with open(input_file) as f:
for line in f: for line in f:
layerline = re.match(r'// LAYER (\d+)', line) layerline = re.match(r'// LAYER (\d+)', line)
if (layerline): if (layerline):
layer = 'constexpr auto CurrentLayer = mtpPrime(' + layerline.group(1) + ');'; layerIndex = int(layerline.group(1));
layer = 'constexpr auto CurrentLayer = mtpPrime(' + str(layerIndex) + ');';
else:
lines.append(line);
for line in lines:
nocomment = re.match(r'^(.*?)//', line) nocomment = re.match(r'^(.*?)//', line)
if (nocomment): if (nocomment):
line = nocomment.group(1); line = nocomment.group(1);
@ -131,8 +142,9 @@ with open(input_file) as f:
if (typeid and len(typeid) > 0): if (typeid and len(typeid) > 0):
typeid = '0x' + typeid; typeid = '0x' + typeid;
if (typeid != countTypeId): if (typeid != countTypeId):
print('Warning: counted ' + countTypeId + ' mismatch with provided ' + typeid + ' (' + cleanline + ')'); if (not layerIndex in countedTypeIdExceptions or not name in countedTypeIdExceptions[layerIndex]):
continue; print('Warning: counted ' + countTypeId + ' mismatch with provided ' + typeid + ' (' + cleanline + ')');
continue;
else: else:
typeid = countTypeId; typeid = countTypeId;

View File

@ -152,11 +152,11 @@ static const BuiltInDc _builtInDcs[] = {
}; };
static const BuiltInDc _builtInDcsIPv6[] = { static const BuiltInDc _builtInDcsIPv6[] = {
{ 1, "2001:b28:f23d:f001::a", 443 }, { 1, "2001:0b28:f23d:f001:0000:0000:0000:000a", 443 },
{ 2, "2001:67c:4e8:f002::a", 443 }, { 2, "2001:067c:04e8:f002:0000:0000:0000:000a", 443 },
{ 3, "2001:b28:f23d:f003::a", 443 }, { 3, "2001:0b28:f23d:f003:0000:0000:0000:000a", 443 },
{ 4, "2001:67c:4e8:f004::a", 443 }, { 4, "2001:067c:04e8:f004:0000:0000:0000:000a", 443 },
{ 5, "2001:b28:f23f:f005::a", 443 } { 5, "2001:0b28:f23f:f005:0000:0000:0000:000a", 443 }
}; };
static const BuiltInDc _builtInTestDcs[] = { static const BuiltInDc _builtInTestDcs[] = {
@ -166,9 +166,9 @@ static const BuiltInDc _builtInTestDcs[] = {
}; };
static const BuiltInDc _builtInTestDcsIPv6[] = { static const BuiltInDc _builtInTestDcsIPv6[] = {
{ 1, "2001:b28:f23d:f001::e", 443 }, { 1, "2001:0b28:f23d:f001:0000:0000:0000:000e", 443 },
{ 2, "2001:67c:4e8:f002::e", 443 }, { 2, "2001:067c:04e8:f002:0000:0000:0000:000e", 443 },
{ 3, "2001:b28:f23d:f003::e", 443 } { 3, "2001:0b28:f23d:f003:0000:0000:0000:000e", 443 }
}; };
inline const BuiltInDc *builtInDcs() { inline const BuiltInDc *builtInDcs() {

View File

@ -114,28 +114,15 @@ MTPinputPeerNotifySettings NotifySettingsValue::serialize() const {
} }
bool NotifySettings::change(const MTPPeerNotifySettings &settings) { bool NotifySettings::change(const MTPPeerNotifySettings &settings) {
switch (settings.type()) { Expects(settings.type() == mtpc_peerNotifySettings);
case mtpc_peerNotifySettingsEmpty: {
if (!_known || _value) {
_known = true;
_value = nullptr;
return true;
}
return false;
} break;
case mtpc_peerNotifySettings: { auto &data = settings.c_peerNotifySettings();
auto &data = settings.c_peerNotifySettings(); if (_value) {
if (_value) { return _value->change(data);
return _value->change(data);
}
_known = true;
_value = std::make_unique<NotifySettingsValue>(data);
return true;
} break;
} }
_known = true;
Unexpected("Type in NotifySettings::change()"); _value = std::make_unique<NotifySettingsValue>(data);
return true;
} }
NotifySettings::NotifySettings() = default; NotifySettings::NotifySettings() = default;
@ -152,18 +139,6 @@ bool NotifySettings::change(
if (_value) { if (_value) {
return _value->change(mute, silent, muteForSeconds); return _value->change(mute, silent, muteForSeconds);
} }
const auto asEmpty = [&] {
if (mute == MuteChange::Mute) {
return false;
}
if (silent == SilentPostsChange::Silent) {
return false;
}
return true;
}();
if (asEmpty) {
return change(MTP_peerNotifySettingsEmpty());
}
const auto flags = MTPDpeerNotifySettings::Flag::f_show_previews const auto flags = MTPDpeerNotifySettings::Flag::f_show_previews
| ((silent == SilentPostsChange::Silent) | ((silent == SilentPostsChange::Silent)
? MTPDpeerNotifySettings::Flag::f_silent ? MTPDpeerNotifySettings::Flag::f_silent

View File

@ -139,13 +139,15 @@ 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);
_instance->dcOptions()->constructAddOne( _instance->dcOptions()->constructAddOne(
_specialEnumCurrent, _specialEnumCurrent,
MTPDdcOption::Flag::f_tcpo_only, MTPDdcOption::Flag::f_tcpo_only,
endpoint->ip, endpoint->ip,
endpoint->port); endpoint->port,
secret);
_specialEnumRequest = _instance->send( _specialEnumRequest = _instance->send(
MTPhelp_GetConfig(), MTPhelp_GetConfig(),
rpcDone([weak](const MTPConfig &result) { rpcDone([weak](const MTPConfig &result) {

View File

@ -362,7 +362,8 @@ void ConnectionPrivate::appendTestConnection(
QWriteLocker lock(&stateConnMutex); QWriteLocker lock(&stateConnMutex);
const auto priority = (qthelp::is_ipv6(ip) ? 0 : 1) const auto priority = (qthelp::is_ipv6(ip) ? 0 : 1)
+ (protocol == DcOptions::Variants::Tcp ? 1 : 0); + (protocol == DcOptions::Variants::Tcp ? 1 : 0)
+ (protocolSecret.empty() ? 0 : 1);
_testConnections.push_back({ _testConnections.push_back({
AbstractConnection::create(protocol, thread()), AbstractConnection::create(protocol, thread()),
priority priority

View File

@ -112,7 +112,7 @@ void DcOptions::constructFromBuiltIn() {
idWithShift, idWithShift,
std::vector<Option>( std::vector<Option>(
1, 1,
Option(bdc.id, flags, bdc.ip, bdc.port))); 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));
} }
@ -126,7 +126,7 @@ void DcOptions::constructFromBuiltIn() {
idWithShift, idWithShift,
std::vector<Option>( std::vector<Option>(
1, 1,
Option(bdc.id, flags, bdc.ip, bdc.port))); 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));
} }
@ -168,7 +168,10 @@ void DcOptions::processFromList(
option.vip_address.v.constData(), option.vip_address.v.constData(),
option.vip_address.v.size()); option.vip_address.v.size());
auto port = option.vport.v; auto port = option.vport.v;
if (applyOneGuarded(dcId, flags, ip, port)) { 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)) { if (!base::contains(idsChanged, dcId)) {
idsChanged.push_back(dcId); idsChanged.push_back(dcId);
} }
@ -220,11 +223,12 @@ void DcOptions::addFromOther(DcOptions &&options) {
WriteLocker lock(this); WriteLocker lock(this);
for (const auto &item : base::take(options._data)) { for (const auto &item : base::take(options._data)) {
for (const auto &option : item.second) { for (const auto &option : item.second) {
auto dcId = option.id; const auto dcId = option.id;
auto flags = option.flags; const auto flags = option.flags;
auto &ip = option.ip; const auto &ip = option.ip;
auto port = option.port; const auto port = option.port;
if (applyOneGuarded(dcId, flags, ip, port)) { const auto &secret = option.secret;
if (applyOneGuarded(dcId, flags, ip, port, secret)) {
if (!base::contains(idsChanged, dcId)) { if (!base::contains(idsChanged, dcId)) {
idsChanged.push_back(dcId); idsChanged.push_back(dcId);
} }
@ -244,16 +248,22 @@ void DcOptions::addFromOther(DcOptions &&options) {
} }
} }
void DcOptions::constructAddOne(int id, MTPDdcOption::Flags flags, const std::string &ip, int port) { void DcOptions::constructAddOne(
int id,
MTPDdcOption::Flags flags,
const std::string &ip,
int port,
const bytes::vector &secret) {
WriteLocker lock(this); WriteLocker lock(this);
applyOneGuarded(bareDcId(id), flags, ip, port); applyOneGuarded(bareDcId(id), flags, ip, port, secret);
} }
bool DcOptions::applyOneGuarded( bool DcOptions::applyOneGuarded(
DcId dcId, DcId dcId,
MTPDdcOption::Flags flags, MTPDdcOption::Flags flags,
const std::string &ip, const std::string &ip,
int port) { int port,
const bytes::vector &secret) {
auto dcIdWithShift = MTP::shiftDcId(dcId, flags); auto dcIdWithShift = MTP::shiftDcId(dcId, flags);
auto i = _data.find(dcIdWithShift); auto i = _data.find(dcIdWithShift);
if (i != _data.cend()) { if (i != _data.cend()) {
@ -262,11 +272,11 @@ bool DcOptions::applyOneGuarded(
return false; return false;
} }
} }
i->second.push_back(Option(dcId, flags, ip, port)); i->second.push_back(Option(dcId, flags, ip, port, secret));
} else { } else {
_data.emplace(dcIdWithShift, std::vector<Option>( _data.emplace(dcIdWithShift, std::vector<Option>(
1, 1,
Option(dcId, flags, ip, port))); Option(dcId, flags, ip, port, secret)));
} }
return true; return true;
} }
@ -280,16 +290,24 @@ QByteArray DcOptions::serialize() const {
ReadLocker lock(this); ReadLocker lock(this);
auto size = sizeof(qint32); auto size = sizeof(qint32);
// Dc options.
auto optionsCount = 0;
size += sizeof(qint32);
for (const auto &item : _data) { for (const auto &item : _data) {
if (isTemporaryDcId(item.first)) { if (isTemporaryDcId(item.first)) {
continue; continue;
} }
for (const auto &option : item.second) { for (const auto &option : item.second) {
size += sizeof(qint32) + sizeof(qint32) + sizeof(qint32); // id + flags + port ++optionsCount;
// id + flags + port
size += sizeof(qint32) + sizeof(qint32) + sizeof(qint32);
size += sizeof(qint32) + option.ip.size(); size += sizeof(qint32) + option.ip.size();
size += sizeof(qint32) + option.secret.size();
} }
} }
// CDN public keys.
auto count = 0; auto count = 0;
for (auto &keysInDc : _cdnPublicKeys) { for (auto &keysInDc : _cdnPublicKeys) {
count += keysInDc.second.size(); count += keysInDc.second.size();
@ -301,32 +319,54 @@ QByteArray DcOptions::serialize() const {
}; };
std::vector<SerializedPublicKey> publicKeys; std::vector<SerializedPublicKey> publicKeys;
publicKeys.reserve(count); publicKeys.reserve(count);
size += sizeof(qint32);
for (const auto &keysInDc : _cdnPublicKeys) { for (const auto &keysInDc : _cdnPublicKeys) {
for (const auto &entry : keysInDc.second) { for (const auto &entry : keysInDc.second) {
publicKeys.push_back({ keysInDc.first, entry.second.getN(), entry.second.getE() }); publicKeys.push_back({
size += sizeof(qint32) + Serialize::bytesSize(publicKeys.back().n) + Serialize::bytesSize(publicKeys.back().e); keysInDc.first,
entry.second.getN(),
entry.second.getE()
});
size += sizeof(qint32)
+ Serialize::bytesSize(publicKeys.back().n)
+ Serialize::bytesSize(publicKeys.back().e);
} }
} }
constexpr auto kVersion = 1;
auto result = QByteArray(); auto result = QByteArray();
result.reserve(size); result.reserve(size);
{ {
QDataStream stream(&result, QIODevice::WriteOnly); QDataStream stream(&result, QIODevice::WriteOnly);
stream.setVersion(QDataStream::Qt_5_1); stream.setVersion(QDataStream::Qt_5_1);
stream << qint32(_data.size()); stream << qint32(-kVersion);
// Dc options.
stream << qint32(optionsCount);
for (const auto &item : _data) { for (const auto &item : _data) {
if (isTemporaryDcId(item.first)) { if (isTemporaryDcId(item.first)) {
continue; continue;
} }
for (const auto &option : item.second) { for (const auto &option : item.second) {
stream << qint32(option.id) << qint32(option.flags) << qint32(option.port); stream << qint32(option.id)
stream << qint32(option.ip.size()); << qint32(option.flags)
<< qint32(option.port)
<< qint32(option.ip.size());
stream.writeRawData(option.ip.data(), option.ip.size()); stream.writeRawData(option.ip.data(), option.ip.size());
stream << qint32(option.secret.size());
stream.writeRawData(
reinterpret_cast<const char*>(option.secret.data()),
option.secret.size());
} }
} }
// CDN public keys.
stream << qint32(publicKeys.size()); stream << qint32(publicKeys.size());
for (auto &key : publicKeys) { for (auto &key : publicKeys) {
stream << qint32(key.dcId) << Serialize::bytes(key.n) << Serialize::bytes(key.e); stream << qint32(key.dcId)
<< Serialize::bytes(key.n)
<< Serialize::bytes(key.e);
} }
} }
return result; return result;
@ -335,8 +375,17 @@ QByteArray DcOptions::serialize() const {
void DcOptions::constructFromSerialized(const QByteArray &serialized) { void DcOptions::constructFromSerialized(const QByteArray &serialized) {
QDataStream stream(serialized); QDataStream stream(serialized);
stream.setVersion(QDataStream::Qt_5_1); stream.setVersion(QDataStream::Qt_5_1);
auto minusVersion = qint32(0);
stream >> minusVersion;
const auto version = (minusVersion < 0) ? (-minusVersion) : 0;
auto count = qint32(0); auto count = qint32(0);
stream >> count; if (version > 0) {
stream >> count;
} else {
count = minusVersion;
}
if (stream.status() != QDataStream::Ok) { if (stream.status() != QDataStream::Ok) {
LOG(("MTP Error: Bad data for DcOptions::constructFromSerialized()")); LOG(("MTP Error: Bad data for DcOptions::constructFromSerialized()"));
return; return;
@ -356,14 +405,35 @@ void DcOptions::constructFromSerialized(const QByteArray &serialized) {
} }
std::string ip(ipSize, ' '); std::string ip(ipSize, ' ');
stream.readRawData(&ip[0], ipSize); stream.readRawData(ip.data(), ipSize);
constexpr auto kMaxSecretSize = 32;
auto secret = bytes::vector();
if (version > 0) {
auto secretSize = qint32(0);
stream >> secretSize;
if (secretSize < 0 || secretSize > kMaxSecretSize) {
LOG(("MTP Error: Bad data inside DcOptions::constructFromSerialized()"));
return;
} else if (secretSize > 0) {
secret.resize(secretSize);
stream.readRawData(
reinterpret_cast<char*>(secret.data()),
secretSize);
}
}
if (stream.status() != QDataStream::Ok) { if (stream.status() != QDataStream::Ok) {
LOG(("MTP Error: Bad data inside DcOptions::constructFromSerialized()")); LOG(("MTP Error: Bad data inside DcOptions::constructFromSerialized()"));
return; return;
} }
applyOneGuarded(DcId(id), MTPDdcOption::Flags::from_raw(flags), ip, port); applyOneGuarded(
DcId(id),
MTPDdcOption::Flags::from_raw(flags),
ip,
port,
secret);
} }
// Read CDN config // Read CDN config
@ -485,8 +555,10 @@ DcOptions::Variants DcOptions::lookup(
switch (protocol) { switch (protocol) {
case Variants::Tcp: return { case Variants::Tcp: return {
// Regular TCP IPv4 // 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_tcpo_only | MTPDdcOption::Flag::f_static) : (MTPDdcOption::Flag::f_tcpo_only | 0),
throughProxy ? (MTPDdcOption::Flag::f_static | 0) : MTPDdcOption::Flags(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), (MTPDdcOption::Flag::f_tcpo_only | 0),
0 0
}; };
@ -501,8 +573,10 @@ DcOptions::Variants DcOptions::lookup(
switch (protocol) { switch (protocol) {
case Variants::Tcp: return { case Variants::Tcp: return {
// Regular TCP IPv6 // 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_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), 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_tcpo_only | MTPDdcOption::Flag::f_ipv6),
(MTPDdcOption::Flag::f_ipv6 | 0), (MTPDdcOption::Flag::f_ipv6 | 0),
}; };
@ -521,12 +595,17 @@ DcOptions::Variants DcOptions::lookup(
switch (protocol) { switch (protocol) {
case Variants::Tcp: return { case Variants::Tcp: return {
// Media download TCP IPv4 // 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_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), throughProxy ? (MTPDdcOption::Flag::f_media_only | MTPDdcOption::Flag::f_static) : (MTPDdcOption::Flag::f_tcpo_only | 0),
(MTPDdcOption::Flag::f_media_only | 0), (MTPDdcOption::Flag::f_media_only | 0),
throughProxy ? (MTPDdcOption::Flag::f_static | 0) : MTPDdcOption::Flags(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), (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_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), throughProxy ? (MTPDdcOption::Flag::f_tcpo_only | 0) : (MTPDdcOption::Flag::f_media_only | 0),
0, 0,
}; };
@ -543,12 +622,17 @@ DcOptions::Variants DcOptions::lookup(
switch (protocol) { switch (protocol) {
case Variants::Tcp: return { case Variants::Tcp: return {
// Media download TCP IPv6 // 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_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), 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), (MTPDdcOption::Flag::f_media_only | MTPDdcOption::Flag::f_ipv6),
throughProxy ? (MTPDdcOption::Flag::f_ipv6 | MTPDdcOption::Flag::f_static) : (MTPDdcOption::Flag::f_ipv6 | 0), 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), (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_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), throughProxy ? (MTPDdcOption::Flag::f_tcpo_only | MTPDdcOption::Flag::f_ipv6) : (MTPDdcOption::Flag::f_media_only | MTPDdcOption::Flag::f_ipv6),
(MTPDdcOption::Flag::f_ipv6 | 0) (MTPDdcOption::Flag::f_ipv6 | 0)
}; };
@ -569,8 +653,10 @@ DcOptions::Variants DcOptions::lookup(
switch (protocol) { switch (protocol) {
case Variants::Tcp: return { case Variants::Tcp: return {
// CDN TCP IPv4 // 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_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), 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 | MTPDdcOption::Flag::f_tcpo_only),
(MTPDdcOption::Flag::f_cdn | 0), (MTPDdcOption::Flag::f_cdn | 0),
}; };
@ -585,8 +671,10 @@ DcOptions::Variants DcOptions::lookup(
switch (protocol) { switch (protocol) {
case Variants::Tcp: return { case Variants::Tcp: return {
// CDN TCP IPv6 // 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_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), 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_tcpo_only | MTPDdcOption::Flag::f_ipv6),
(MTPDdcOption::Flag::f_cdn | MTPDdcOption::Flag::f_ipv6), (MTPDdcOption::Flag::f_cdn | MTPDdcOption::Flag::f_ipv6),
}; };
@ -616,7 +704,8 @@ DcOptions::Variants DcOptions::lookup(
for (const auto &option : it->second) { for (const auto &option : it->second) {
result.data[address][protocol].push_back({ result.data[address][protocol].push_back({
option.ip, option.ip,
option.port option.port,
option.secret
}); });
} }
break; break;
@ -684,7 +773,12 @@ bool DcOptions::loadFromFile(const QString &path) {
return error(); return error();
} }
} }
options.push_back(MTP_dcOption(MTP_flags(flags), MTP_int(dcId), MTP_string(ip), MTP_int(port))); options.push_back(MTP_dcOption(
MTP_flags(flags),
MTP_int(dcId),
MTP_string(ip),
MTP_int(port),
MTPbytes()));
} }
if (options.isEmpty()) { if (options.isEmpty()) {
LOG(("MTP Error: in .tdesktop-endpoints expected at least one endpoint being provided.")); LOG(("MTP Error: in .tdesktop-endpoints expected at least one endpoint being provided."));

View File

@ -31,7 +31,8 @@ public:
int id, int id,
MTPDdcOption::Flags flags, MTPDdcOption::Flags flags,
const std::string &ip, const std::string &ip,
int port); int port,
const bytes::vector &secret);
QByteArray serialize() const; QByteArray serialize() const;
using Ids = std::vector<DcId>; using Ids = std::vector<DcId>;
@ -75,15 +76,32 @@ public:
private: private:
struct Option { struct Option {
Option(DcId id, MTPDdcOption::Flags flags, const std::string &ip, int port) : id(id), flags(flags), ip(ip), port(port) { 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; DcId id;
MTPDdcOption::Flags flags; MTPDdcOption::Flags flags;
std::string ip; std::string ip;
int port; int port;
bytes::vector secret;
}; };
bool applyOneGuarded(DcId dcId, MTPDdcOption::Flags flags, const std::string &ip, int port); bool applyOneGuarded(
DcId dcId,
MTPDdcOption::Flags flags,
const std::string &ip,
int port,
const bytes::vector &secret);
void processFromList(const QVector<MTPDcOption> &options, bool overwrite); void processFromList(const QVector<MTPDcOption> &options, bool overwrite);
void computeCdnDcIds(); void computeCdnDcIds();

View File

@ -872,7 +872,12 @@ bool _readSetting(quint32 blockId, QDataStream &stream, int version, ReadSetting
stream >> dcId >> host >> ip >> port; stream >> dcId >> host >> ip >> port;
if (!_checkStreamStatus(stream)) return false; if (!_checkStreamStatus(stream)) return false;
context.dcOptions.constructAddOne(dcId, 0, ip.toStdString(), port); context.dcOptions.constructAddOne(
dcId,
0,
ip.toStdString(),
port,
{});
} break; } break;
case dbiDcOptionOld: { case dbiDcOptionOld: {
@ -882,7 +887,12 @@ bool _readSetting(quint32 blockId, QDataStream &stream, int version, ReadSetting
stream >> dcIdWithShift >> flags >> ip >> port; stream >> dcIdWithShift >> flags >> ip >> port;
if (!_checkStreamStatus(stream)) return false; if (!_checkStreamStatus(stream)) return false;
context.dcOptions.constructAddOne(dcIdWithShift, MTPDdcOption::Flags::from_raw(flags), ip.toStdString(), port); context.dcOptions.constructAddOne(
dcIdWithShift,
MTPDdcOption::Flags::from_raw(flags),
ip.toStdString(),
port,
{});
} break; } break;
case dbiDcOptions: { case dbiDcOptions: {