/* This file is part of Telegram Desktop, the official desktop application for the Telegram messaging service. For license and copyright information please follow this link: https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL */ #pragma once #include "base/observer.h" #include "base/bytes.h" #include "mtproto/rsa_public_key.h" #include #include #include #include #include namespace MTP { enum class DcType { Regular, Temporary, MediaDownload, Cdn, }; class DcOptions { 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; }; DcOptions(); [[nodiscard]] static bool ValidateSecret(bytes::const_span secret); // construct methods don't notify "changed" subscribers. void constructFromSerialized(const QByteArray &serialized); void constructFromBuiltIn(); void constructAddOne( int id, Flags flags, const std::string &ip, int port, const bytes::vector &secret); QByteArray serialize() const; using Ids = std::vector; base::Observable &changed() const { return _changed; } void setFromList(const MTPVector &options); void addFromList(const MTPVector &options); void addFromOther(DcOptions &&options); Ids configEnumDcIds() const; struct Variants { enum Address { IPv4 = 0, IPv6 = 1, AddressTypeCount = 2, }; enum Protocol { Tcp = 0, Http = 1, ProtocolCount = 2, }; std::vector data[AddressTypeCount][ProtocolCount]; }; Variants lookup(DcId dcId, DcType type, bool throughProxy) const; DcType dcType(ShiftedDcId shiftedDcId) const; void setCDNConfig(const MTPDcdnConfig &config); [[nodiscard]] bool hasCDNKeysForDc(DcId dcId) const; [[nodiscard]] internal::RSAPublicKey getDcRSAKey( DcId dcId, const QVector &fingerprints) const; // Debug feature for now. bool loadFromFile(const QString &path); bool writeToFile(const QString &path) const; private: bool applyOneGuarded( DcId dcId, Flags flags, const std::string &ip, int port, const bytes::vector &secret); static bool ApplyOneOption( std::map> &data, DcId dcId, Flags flags, const std::string &ip, int port, const bytes::vector &secret); static Ids CountOptionsDifference( const std::map> &a, const std::map> &b); static void FilterIfHasWithFlag(Variants &variants, Flag flag); void processFromList(const QVector &options, bool overwrite); void computeCdnDcIds(); void readBuiltInPublicKeys(); class WriteLocker; friend class WriteLocker; class ReadLocker; friend class ReadLocker; std::map> _data; std::set _cdnDcIds; std::map _publicKeys; std::map> _cdnPublicKeys; mutable QReadWriteLock _useThroughLockers; mutable base::Observable _changed; // True when we have overriden options from a .tdesktop-endpoints file. bool _immutable = false; }; } // namespace MTP