New Proxy API.
GitOrigin-RevId: 2f96b8d1732c25e10a7568c6cf2dbbe26a150e4a
This commit is contained in:
parent
b636b03e5d
commit
7de9a0c15d
@ -117,7 +117,7 @@ temporaryPasswordState has_password:Bool valid_for:int32 = TemporaryPasswordStat
|
||||
localFile path:string can_be_downloaded:Bool can_be_deleted:Bool is_downloading_active:Bool is_downloading_completed:Bool downloaded_prefix_size:int32 downloaded_size:int32 = LocalFile;
|
||||
|
||||
//@description Represents a remote file
|
||||
//@id Remote file identifier, may be empty. Can be used across application restarts or even from other devices for the current user. If the ID starts with "http://" or "https://", it represents the HTTP URL of the file. TDLib is currently unable to download files if only their URL is known.
|
||||
//@id Remote file identifier; may be empty. Can be used across application restarts or even from other devices for the current user. If the ID starts with "http://" or "https://", it represents the HTTP URL of the file. TDLib is currently unable to download files if only their URL is known.
|
||||
//-If downloadFile is called on such a file or if it is sent to a secret chat, TDLib starts a file generation process by sending updateFileGenerationStart to the client with the HTTP URL in the original_path and "#url#" as the conversion string. Clients should generate the file by downloading it to the specified location
|
||||
//@is_uploading_active True, if the file is currently being uploaded (or a remote copy is being generated by some other means)
|
||||
//@is_uploading_completed True, if a remote copy is fully available
|
||||
@ -144,7 +144,7 @@ inputFileRemote id:string = InputFile;
|
||||
//@description A file defined by a local path @path Local path to the file
|
||||
inputFileLocal path:string = InputFile;
|
||||
|
||||
//@description A file generated by the client @original_path Local path to a file from which the file is generated, may be empty if there is no such file @conversion String specifying the conversion applied to the original file; should be persistent across application restarts @expected_size Expected size of the generated file; 0 if unknown
|
||||
//@description A file generated by the client @original_path Local path to a file from which the file is generated; may be empty if there is no such file @conversion String specifying the conversion applied to the original file; should be persistent across application restarts @expected_size Expected size of the generated file; 0 if unknown
|
||||
inputFileGenerated original_path:string conversion:string expected_size:int32 = InputFile;
|
||||
|
||||
|
||||
@ -1119,7 +1119,7 @@ messageGameScore game_message_id:int53 game_id:int64 score:int32 = MessageConten
|
||||
messagePaymentSuccessful invoice_message_id:int53 currency:string total_amount:int53 = MessageContent;
|
||||
|
||||
//@description A payment has been completed; for bots only @invoice_message_id Identifier of the message with the corresponding invoice; can be an identifier of a deleted message @currency Currency for price of the product
|
||||
//@total_amount Total price for the product, in the minimal quantity of the currency @invoice_payload Invoice payload @shipping_option_id Identifier of the shipping option chosen by the user, may be empty if not applicable @order_info Information about the order; may be null
|
||||
//@total_amount Total price for the product, in the minimal quantity of the currency @invoice_payload Invoice payload @shipping_option_id Identifier of the shipping option chosen by the user; may be empty if not applicable @order_info Information about the order; may be null
|
||||
//@telegram_payment_charge_id Telegram payment identifier @provider_payment_charge_id Provider payment identifier
|
||||
messagePaymentSuccessfulBot invoice_message_id:int53 currency:string total_amount:int53 invoice_payload:bytes shipping_option_id:string order_info:orderInfo telegram_payment_charge_id:string provider_payment_charge_id:string = MessageContent;
|
||||
|
||||
@ -1648,38 +1648,38 @@ chatEventLogFilters message_edits:Bool message_deletions:Bool message_pins:Bool
|
||||
|
||||
//@class DeviceToken @description Represents a data needed to subscribe for push notifications. To use specific push notification service, you must specify the correct application platform and upload valid server authentication data at https://my.telegram.org
|
||||
|
||||
//@description A token for Google Cloud Messaging @token Device registration token, may be empty to de-register a device
|
||||
//@description A token for Google Cloud Messaging @token Device registration token; may be empty to de-register a device
|
||||
deviceTokenGoogleCloudMessaging token:string = DeviceToken;
|
||||
|
||||
//@description A token for Apple Push Notification service @device_token Device token, may be empty to de-register a device @is_app_sandbox True, if App Sandbox is enabled
|
||||
//@description A token for Apple Push Notification service @device_token Device token; may be empty to de-register a device @is_app_sandbox True, if App Sandbox is enabled
|
||||
deviceTokenApplePush device_token:string is_app_sandbox:Bool = DeviceToken;
|
||||
|
||||
//@description A token for Apple Push Notification service VoIP notifications @device_token Device token, may be empty to de-register a device @is_app_sandbox True, if App Sandbox is enabled
|
||||
//@description A token for Apple Push Notification service VoIP notifications @device_token Device token; may be empty to de-register a device @is_app_sandbox True, if App Sandbox is enabled
|
||||
deviceTokenApplePushVoIP device_token:string is_app_sandbox:Bool = DeviceToken;
|
||||
|
||||
//@description A token for Windows Push Notification Services @access_token The access token that will be used to send notifications, may be empty to de-register a device
|
||||
//@description A token for Windows Push Notification Services @access_token The access token that will be used to send notifications; may be empty to de-register a device
|
||||
deviceTokenWindowsPush access_token:string = DeviceToken;
|
||||
|
||||
//@description A token for Microsoft Push Notification Service @channel_uri Push notification channel URI, may be empty to de-register a device
|
||||
//@description A token for Microsoft Push Notification Service @channel_uri Push notification channel URI; may be empty to de-register a device
|
||||
deviceTokenMicrosoftPush channel_uri:string = DeviceToken;
|
||||
|
||||
//@description A token for Microsoft Push Notification Service VoIP channel @channel_uri Push notification channel URI, may be empty to de-register a device
|
||||
//@description A token for Microsoft Push Notification Service VoIP channel @channel_uri Push notification channel URI; may be empty to de-register a device
|
||||
deviceTokenMicrosoftPushVoIP channel_uri:string = DeviceToken;
|
||||
|
||||
//@description A token for web Push API @endpoint Absolute URL exposed by the push service where the application server can send push messages, may be empty to de-register a device
|
||||
//@description A token for web Push API @endpoint Absolute URL exposed by the push service where the application server can send push messages; may be empty to de-register a device
|
||||
//@p256dh_base64url Base64url-encoded P-256 elliptic curve Diffie-Hellman public key @auth_base64url Base64url-encoded authentication secret
|
||||
deviceTokenWebPush endpoint:string p256dh_base64url:string auth_base64url:string = DeviceToken;
|
||||
|
||||
//@description A token for Simple Push API for Firefox OS @endpoint Absolute URL exposed by the push service where the application server can send push messages, may be empty to de-register a device
|
||||
//@description A token for Simple Push API for Firefox OS @endpoint Absolute URL exposed by the push service where the application server can send push messages; may be empty to de-register a device
|
||||
deviceTokenSimplePush endpoint:string = DeviceToken;
|
||||
|
||||
//@description A token for Ubuntu Push Client service @token Token, may be empty to de-register a device
|
||||
//@description A token for Ubuntu Push Client service @token Token; may be empty to de-register a device
|
||||
deviceTokenUbuntuPush token:string = DeviceToken;
|
||||
|
||||
//@description A token for BlackBerry Push Service @token Token, may be empty to de-register a device
|
||||
//@description A token for BlackBerry Push Service @token Token; may be empty to de-register a device
|
||||
deviceTokenBlackBerryPush token:string = DeviceToken;
|
||||
|
||||
//@description A token for Tizen Push Service @reg_id Push service registration identifier, may be empty to de-register a device
|
||||
//@description A token for Tizen Push Service @reg_id Push service registration identifier; may be empty to de-register a device
|
||||
deviceTokenTizenPush reg_id:string = DeviceToken;
|
||||
|
||||
|
||||
@ -1979,6 +1979,9 @@ count count:int32 = Count;
|
||||
//@description Contains some text @text Text
|
||||
text text:string = Text;
|
||||
|
||||
//@description Contains a value representing number of seconds @seconds Number of seconds
|
||||
seconds seconds:double = Seconds;
|
||||
|
||||
|
||||
//@description Contains information about a tg:// deep link @text Text to be shown to the user @need_update_application True, if user should be asked to update the application
|
||||
deepLinkInfo text:formattedText need_update_application:Bool = DeepLinkInfo;
|
||||
@ -1993,16 +1996,20 @@ textParseModeMarkdown = TextParseMode;
|
||||
textParseModeHTML = TextParseMode;
|
||||
|
||||
|
||||
//@class Proxy @description Contains information about a proxy server
|
||||
//@class ProxyType @description Describes the type of the proxy server
|
||||
|
||||
//@description An empty proxy server
|
||||
proxyEmpty = Proxy;
|
||||
//@description A SOCKS5 proxy server @username Username for logging in; may be empty @password Password for logging in; may be empty
|
||||
proxyTypeSocks5 username:string password:string = ProxyType;
|
||||
|
||||
//@description A SOCKS5 proxy server @server Proxy server IP address @port Proxy server port @username Username for logging in @password Password for logging in
|
||||
proxySocks5 server:string port:int32 username:string password:string = Proxy;
|
||||
//@description An MTProto proxy server @secret Proxy's secret in hexadecimal encoding
|
||||
proxyTypeMtproto secret:string = ProxyType;
|
||||
|
||||
//@description An MTProro proxy server @server Proxy server IP address @port Proxy server port @secret Server's secret
|
||||
proxyMtproto server:string port:int32 secret:string = Proxy;
|
||||
|
||||
//@description Contains information about a proxy server @id Unique proxy identifier @server Proxy server IP address @port Proxy server port @last_used_date Point in time (Unix timestamp) when the proxy was last used; 0 if never @is_enabled True, if the proxy is enabled now @type Type of a proxy
|
||||
proxy id:int32 server:string port:int32 last_used_date:int32 is_enabled:Bool type:ProxyType = Proxy;
|
||||
|
||||
//@description Represents a list of proxy servers @proxies List of proxy servers
|
||||
proxies proxies:vector<proxy> = Proxies;
|
||||
|
||||
|
||||
//@description Describes a sticker that should be added to a sticker set @png_sticker PNG image with the sticker; must be up to 512 kB in size and fit in a 512x512 square @emojis Emoji corresponding to the sticker @mask_position For masks, position where the mask should be placed; may be null
|
||||
@ -2129,7 +2136,7 @@ updateFile file:file = Update;
|
||||
|
||||
//@description The file generation process needs to be started by the client
|
||||
//@generation_id Unique identifier for the generation process
|
||||
//@original_path The path to a file from which a new file is generated, may be empty
|
||||
//@original_path The path to a file from which a new file is generated; may be empty
|
||||
//@destination_path The path to a file that should be created and where the new file should be generated
|
||||
//@conversion String specifying the conversion applied to the original file. If conversion is "#url#" than original_path contains a HTTP/HTTPS URL of a file, which should be downloaded by the client
|
||||
updateFileGenerationStart generation_id:int64 original_path:string destination_path:string conversion:string = Update;
|
||||
@ -3153,11 +3160,23 @@ getTermsOfService = Text;
|
||||
getDeepLinkInfo link:string = DeepLinkInfo;
|
||||
|
||||
|
||||
//@description Sets the proxy server for network requests. Can be called before authorization @proxy Proxy server to use. Specify null to remove the proxy server
|
||||
setProxy proxy:Proxy = Ok;
|
||||
//@description Adds a proxy server for network requests. Can be called before authorization. Can be called before initialization @server Proxy server IP address @port Proxy server port @enable True, if the proxy should be enabled @type Type of a proxy
|
||||
addProxy server:string port:int32 enable:Bool type:ProxyType = Proxy;
|
||||
|
||||
//@description Returns the proxy that is currently set up. Can be called before authorization
|
||||
getProxy = Proxy;
|
||||
//@description Enables a proxy. Only one proxy can be enabled at a time. Can be called before authorization @proxy_id The proxy identifier
|
||||
enableProxy proxy_id:int32 = Ok;
|
||||
|
||||
//@description Disables currently enabled proxy. Can be called before authorization
|
||||
disableProxy = Ok;
|
||||
|
||||
//@description Removes a proxy server. Can be called before authorization @proxy_id The proxy identifier
|
||||
removeProxy proxy_id:int32 = Ok;
|
||||
|
||||
//@description Returns list of proxies that are currently set up. Can be called before authorization
|
||||
getProxies = Proxies;
|
||||
|
||||
//@description Computes time needed to receive a response from a Telegram server through the proxy. Can be called before authorization @proxy_id The proxy identifier
|
||||
pingProxy proxy_id:int32 = Seconds;
|
||||
|
||||
|
||||
//@description Does nothing; for testing only
|
||||
|
Binary file not shown.
@ -926,6 +926,9 @@ void AuthManager::update_state(State new_state, bool force, bool should_save_sta
|
||||
|
||||
bool AuthManager::load_state() {
|
||||
auto data = G()->td_db()->get_binlog_pmc()->get("auth_state");
|
||||
if (data.empty()) {
|
||||
return false;
|
||||
}
|
||||
DbState db_state;
|
||||
auto status = log_event_parse(db_state, data);
|
||||
if (status.is_error()) {
|
||||
|
@ -25903,7 +25903,11 @@ void MessagesManager::set_promoted_dialog_id(DialogId dialog_id) {
|
||||
}
|
||||
|
||||
if (G()->parameters().use_message_db) {
|
||||
if (promoted_dialog_id_.is_valid()) {
|
||||
G()->td_db()->get_binlog_pmc()->set("promoted_dialog_id", to_string(promoted_dialog_id_.get()));
|
||||
} else {
|
||||
G()->td_db()->get_binlog_pmc()->erase("promoted_dialog_id");
|
||||
}
|
||||
LOG(INFO) << "Save promoted " << promoted_dialog_id_;
|
||||
}
|
||||
|
||||
|
@ -7096,22 +7096,43 @@ void Td::on_request(uint64 id, td_api::getDeepLinkInfo &request) {
|
||||
create_handler<GetDeepLinkInfoQuery>(std::move(promise))->send(request.link_);
|
||||
}
|
||||
|
||||
void Td::on_request(uint64 id, const td_api::getProxy &request) {
|
||||
void Td::on_request(uint64 id, td_api::addProxy &request) {
|
||||
CLEAN_INPUT_STRING(request.server_);
|
||||
CREATE_REQUEST_PROMISE(promise);
|
||||
auto query_promise = PromiseCreator::lambda([promise = std::move(promise)](Result<Proxy> result) mutable {
|
||||
send_closure(G()->connection_creator(), &ConnectionCreator::add_proxy, std::move(request.server_), request.port_,
|
||||
request.enable_, std::move(request.type_), std::move(promise));
|
||||
}
|
||||
|
||||
void Td::on_request(uint64 id, const td_api::enableProxy &request) {
|
||||
CREATE_OK_REQUEST_PROMISE(promise);
|
||||
send_closure(G()->connection_creator(), &ConnectionCreator::enable_proxy, request.proxy_id_, std::move(promise));
|
||||
}
|
||||
|
||||
void Td::on_request(uint64 id, const td_api::disableProxy &request) {
|
||||
CREATE_OK_REQUEST_PROMISE(promise);
|
||||
send_closure(G()->connection_creator(), &ConnectionCreator::disable_proxy, std::move(promise));
|
||||
}
|
||||
|
||||
void Td::on_request(uint64 id, const td_api::removeProxy &request) {
|
||||
CREATE_OK_REQUEST_PROMISE(promise);
|
||||
send_closure(G()->connection_creator(), &ConnectionCreator::remove_proxy, request.proxy_id_, std::move(promise));
|
||||
}
|
||||
|
||||
void Td::on_request(uint64 id, const td_api::getProxies &request) {
|
||||
CREATE_REQUEST_PROMISE(promise);
|
||||
send_closure(G()->connection_creator(), &ConnectionCreator::get_proxies, std::move(promise));
|
||||
}
|
||||
|
||||
void Td::on_request(uint64 id, const td_api::pingProxy &request) {
|
||||
CREATE_REQUEST_PROMISE(promise);
|
||||
auto query_promise = PromiseCreator::lambda([promise = std::move(promise)](Result<double> result) mutable {
|
||||
if (result.is_error()) {
|
||||
promise.set_error(result.move_as_error());
|
||||
} else {
|
||||
promise.set_value(result.move_as_ok().as_td_api());
|
||||
promise.set_value(make_tl_object<td_api::seconds>(result.move_as_ok()));
|
||||
}
|
||||
});
|
||||
send_closure(G()->connection_creator(), &ConnectionCreator::get_proxy, std::move(query_promise));
|
||||
}
|
||||
|
||||
void Td::on_request(uint64 id, const td_api::setProxy &request) {
|
||||
CREATE_OK_REQUEST_PROMISE(promise);
|
||||
send_closure(G()->connection_creator(), &ConnectionCreator::set_proxy, Proxy::from_td_api(request.proxy_));
|
||||
promise.set_value(Unit());
|
||||
send_closure(G()->connection_creator(), &ConnectionCreator::ping_proxy, request.proxy_id_, std::move(query_promise));
|
||||
}
|
||||
|
||||
void Td::on_request(uint64 id, const td_api::getTextEntities &request) {
|
||||
|
@ -800,9 +800,17 @@ class Td final : public NetQueryCallback {
|
||||
|
||||
void on_request(uint64 id, td_api::getDeepLinkInfo &request);
|
||||
|
||||
void on_request(uint64 id, const td_api::getProxy &request);
|
||||
void on_request(uint64 id, td_api::addProxy &request);
|
||||
|
||||
void on_request(uint64 id, const td_api::setProxy &request);
|
||||
void on_request(uint64 id, const td_api::enableProxy &request);
|
||||
|
||||
void on_request(uint64 id, const td_api::disableProxy &request);
|
||||
|
||||
void on_request(uint64 id, const td_api::removeProxy &request);
|
||||
|
||||
void on_request(uint64 id, const td_api::getProxies &request);
|
||||
|
||||
void on_request(uint64 id, const td_api::pingProxy &request);
|
||||
|
||||
void on_request(uint64 id, const td_api::getTextEntities &request);
|
||||
|
||||
|
@ -437,10 +437,6 @@ class CliClient final : public Actor {
|
||||
return to_integer<int32>(trim(std::move(str)));
|
||||
}
|
||||
|
||||
static int32 as_call_id(string str) {
|
||||
return to_integer<int32>(trim(std::move(str)));
|
||||
}
|
||||
|
||||
static td_api::object_ptr<td_api::InputFile> as_input_file_id(string str) {
|
||||
return make_tl_object<td_api::inputFileId>(as_file_id(str));
|
||||
}
|
||||
@ -473,6 +469,14 @@ class CliClient final : public Actor {
|
||||
return as_local_file(str);
|
||||
}
|
||||
|
||||
static int32 as_call_id(string str) {
|
||||
return to_integer<int32>(trim(std::move(str)));
|
||||
}
|
||||
|
||||
static int32 as_proxy_id(string str) {
|
||||
return to_integer<int32>(trim(std::move(str)));
|
||||
}
|
||||
|
||||
static tl_object_ptr<td_api::location> as_location(string latitude, string longitude) {
|
||||
return make_tl_object<td_api::location>(to_double(latitude), to_double(longitude));
|
||||
}
|
||||
@ -3052,9 +3056,13 @@ class CliClient final : public Actor {
|
||||
as_message_ids(message_ids)));
|
||||
} else if (op == "gdiff") {
|
||||
send_request(make_tl_object<td_api::testGetDifference>());
|
||||
} else if (op == "cproxy") {
|
||||
send_request(make_tl_object<td_api::setProxy>(make_tl_object<td_api::proxyEmpty>()));
|
||||
} else if (op == "sproxy") {
|
||||
} else if (op == "dproxy") {
|
||||
send_request(make_tl_object<td_api::disableProxy>());
|
||||
} else if (op == "eproxy") {
|
||||
send_request(make_tl_object<td_api::enableProxy>(as_proxy_id(args)));
|
||||
} else if (op == "rproxy") {
|
||||
send_request(make_tl_object<td_api::removeProxy>(as_proxy_id(args)));
|
||||
} else if (op == "aproxy" || op == "aeproxy") {
|
||||
string server;
|
||||
string port;
|
||||
string user;
|
||||
@ -3062,15 +3070,17 @@ class CliClient final : public Actor {
|
||||
std::tie(server, args) = split(args);
|
||||
std::tie(port, args) = split(args);
|
||||
std::tie(user, password) = split(args);
|
||||
td_api::object_ptr<td_api::ProxyType> type;
|
||||
if (!user.empty() && password.empty()) {
|
||||
send_request(make_tl_object<td_api::setProxy>(
|
||||
make_tl_object<td_api::proxyMtproto>(server, to_integer<int32>(port), user)));
|
||||
type = make_tl_object<td_api::proxyTypeMtproto>(user);
|
||||
} else {
|
||||
send_request(make_tl_object<td_api::setProxy>(
|
||||
make_tl_object<td_api::proxySocks5>(server, to_integer<int32>(port), user, password)));
|
||||
type = make_tl_object<td_api::proxyTypeSocks5>(user, password);
|
||||
}
|
||||
} else if (op == "gproxy") {
|
||||
send_request(make_tl_object<td_api::getProxy>());
|
||||
send_request(make_tl_object<td_api::addProxy>(server, to_integer<int32>(port), op == "aeproxy", std::move(type)));
|
||||
} else if (op == "gproxy" || op == "gproxies") {
|
||||
send_request(make_tl_object<td_api::getProxies>());
|
||||
} else if (op == "pproxy") {
|
||||
send_request(make_tl_object<td_api::pingProxy>(as_proxy_id(args)));
|
||||
} else if (op == "touch") {
|
||||
auto r_fd = FileFd::open(args, FileFd::Read | FileFd::Write);
|
||||
if (r_fd.is_error()) {
|
||||
@ -3083,7 +3093,7 @@ class CliClient final : public Actor {
|
||||
fd.write("a").ignore();
|
||||
fd.seek(size).ignore();
|
||||
fd.truncate_to_current_position(size).ignore();
|
||||
} else if (op == "SetVerbosity") {
|
||||
} else if (op == "SetVerbosity" || op == "SV") {
|
||||
td::Log::set_verbosity_level(to_integer<int>(args));
|
||||
} else if (op == "q" || op == "Quit") {
|
||||
quit();
|
||||
|
@ -32,6 +32,7 @@
|
||||
#include "td/utils/tl_helpers.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <utility>
|
||||
|
||||
namespace td {
|
||||
|
||||
@ -215,35 +216,143 @@ void ConnectionCreator::set_net_stats_callback(std::shared_ptr<NetStatsCallback>
|
||||
media_net_stats_callback_ = std::move(media_callback);
|
||||
}
|
||||
|
||||
void ConnectionCreator::set_proxy(Proxy proxy) {
|
||||
set_proxy_impl(std::move(proxy), false);
|
||||
loop();
|
||||
void ConnectionCreator::add_proxy(string server, int32 port, bool enable,
|
||||
td_api::object_ptr<td_api::ProxyType> proxy_type,
|
||||
Promise<td_api::object_ptr<td_api::proxy>> promise) {
|
||||
if (proxy_type == nullptr) {
|
||||
return promise.set_error(Status::Error(400, "Proxy type should not be empty"));
|
||||
}
|
||||
if (server.empty()) {
|
||||
return promise.set_error(Status::Error(400, "Server name can't be empty"));
|
||||
}
|
||||
if (port <= 0 || port > 65535) {
|
||||
return promise.set_error(Status::Error(400, "Wrong port number"));
|
||||
}
|
||||
|
||||
void ConnectionCreator::set_proxy_impl(Proxy proxy, bool from_db) {
|
||||
auto have_proxy = proxy.type() != Proxy::Type::None;
|
||||
if (proxy_ == proxy) {
|
||||
if (!have_proxy) {
|
||||
on_get_proxy_info(make_tl_object<telegram_api::help_proxyDataEmpty>(0));
|
||||
Proxy new_proxy;
|
||||
switch (proxy_type->get_id()) {
|
||||
case td_api::proxyTypeSocks5::ID: {
|
||||
auto type = td_api::move_object_as<td_api::proxyTypeSocks5>(proxy_type);
|
||||
new_proxy = Proxy::socks5(server, port, type->username_, type->password_);
|
||||
break;
|
||||
}
|
||||
case td_api::proxyTypeMtproto::ID: {
|
||||
auto type = td_api::move_object_as<td_api::proxyTypeMtproto>(proxy_type);
|
||||
if (type->secret_.size() != 32 || hex_decode(type->secret_).is_error()) {
|
||||
return promise.set_error(Status::Error(400, "Wrong server secret"));
|
||||
}
|
||||
new_proxy = Proxy::mtproto(server, port, type->secret_);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
UNREACHABLE();
|
||||
}
|
||||
|
||||
auto proxy_id = [&] {
|
||||
for (auto &proxy : proxies_) {
|
||||
if (proxy.second == new_proxy) {
|
||||
return proxy.first;
|
||||
}
|
||||
}
|
||||
|
||||
CHECK(max_proxy_id_ >= 2);
|
||||
auto proxy_id = max_proxy_id_++;
|
||||
G()->td_db()->get_binlog_pmc()->set("proxy_max_id", to_string(max_proxy_id_));
|
||||
CHECK(proxies_.count(proxy_id) == 0);
|
||||
proxies_.emplace(proxy_id, std::move(new_proxy));
|
||||
G()->td_db()->get_binlog_pmc()->set(get_proxy_database_key(proxy_id),
|
||||
log_event_store(proxies_[proxy_id]).as_slice().str());
|
||||
}();
|
||||
if (enable) {
|
||||
enable_proxy_impl(proxy_id);
|
||||
}
|
||||
promise.set_value(get_proxy_object(proxy_id));
|
||||
}
|
||||
|
||||
void ConnectionCreator::enable_proxy(int32 proxy_id, Promise<Unit> promise) {
|
||||
if (proxies_.count(proxy_id) == 0) {
|
||||
return promise.set_error(Status::Error(400, "Unknown proxy identifier"));
|
||||
}
|
||||
|
||||
enable_proxy_impl(proxy_id);
|
||||
promise.set_value(Unit());
|
||||
}
|
||||
|
||||
void ConnectionCreator::disable_proxy(Promise<Unit> promise) {
|
||||
disable_proxy_impl();
|
||||
promise.set_value(Unit());
|
||||
}
|
||||
|
||||
void ConnectionCreator::remove_proxy(int32 proxy_id, Promise<Unit> promise) {
|
||||
if (proxies_.count(proxy_id) == 0) {
|
||||
return promise.set_error(Status::Error(400, "Unknown proxy identifier"));
|
||||
}
|
||||
|
||||
if (proxy_id == active_proxy_id_) {
|
||||
disable_proxy_impl();
|
||||
}
|
||||
|
||||
proxies_.erase(proxy_id);
|
||||
|
||||
G()->td_db()->get_binlog_pmc()->erase(get_proxy_database_key(proxy_id));
|
||||
G()->td_db()->get_binlog_pmc()->erase(get_proxy_used_database_key(proxy_id));
|
||||
promise.set_value(Unit());
|
||||
}
|
||||
|
||||
void ConnectionCreator::get_proxies(Promise<td_api::object_ptr<td_api::proxies>> promise) {
|
||||
promise.set_value(td_api::make_object<td_api::proxies>(
|
||||
transform(proxies_, [this](const std::pair<int32, Proxy> &proxy) { return get_proxy_object(proxy.first); })));
|
||||
}
|
||||
|
||||
void ConnectionCreator::ping_proxy(int32 proxy_id, Promise<double> promise) {
|
||||
if (proxies_.count(proxy_id) == 0) {
|
||||
return promise.set_error(Status::Error(400, "Unknown proxy identifier"));
|
||||
}
|
||||
|
||||
// TODO ping
|
||||
promise.set_value(0.0);
|
||||
}
|
||||
|
||||
void ConnectionCreator::enable_proxy_impl(int32 proxy_id) {
|
||||
CHECK(proxies_.count(proxy_id) == 1);
|
||||
if (proxy_id == active_proxy_id_) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (proxy_.type() == Proxy::Type::Mtproto || proxy.type() == Proxy::Type::Mtproto) {
|
||||
G()->mtproto_header().set_proxy(proxy);
|
||||
if ((active_proxy_id_ != 0 && proxies_[active_proxy_id_].type() == Proxy::Type::Mtproto) ||
|
||||
proxies_[proxy_id].type() == Proxy::Type::Mtproto) {
|
||||
G()->mtproto_header().set_proxy(proxies_[proxy_id]);
|
||||
G()->net_query_dispatcher().update_mtproto_header();
|
||||
}
|
||||
|
||||
proxy_ = std::move(proxy);
|
||||
active_proxy_id_ = proxy_id;
|
||||
G()->td_db()->get_binlog_pmc()->set("proxy_active_id", to_string(proxy_id));
|
||||
|
||||
send_closure(G()->state_manager(), &StateManager::on_proxy, have_proxy);
|
||||
on_proxy_changed(false);
|
||||
}
|
||||
|
||||
void ConnectionCreator::disable_proxy_impl() {
|
||||
if (active_proxy_id_ == 0) {
|
||||
on_get_proxy_info(make_tl_object<telegram_api::help_proxyDataEmpty>(0));
|
||||
return;
|
||||
}
|
||||
CHECK(proxies_.count(active_proxy_id_) == 1);
|
||||
|
||||
if (proxies_[active_proxy_id_].type() == Proxy::Type::Mtproto) {
|
||||
G()->mtproto_header().set_proxy(Proxy());
|
||||
G()->net_query_dispatcher().update_mtproto_header();
|
||||
}
|
||||
|
||||
active_proxy_id_ = 0;
|
||||
G()->td_db()->get_binlog_pmc()->erase("proxy_active_id");
|
||||
|
||||
on_proxy_changed(false);
|
||||
}
|
||||
|
||||
void ConnectionCreator::on_proxy_changed(bool from_db) {
|
||||
send_closure(G()->state_manager(), &StateManager::on_proxy, active_proxy_id_ != 0);
|
||||
|
||||
if (!from_db) {
|
||||
if (have_proxy) {
|
||||
G()->td_db()->get_binlog_pmc()->set("proxy", log_event_store(proxy_).as_slice().str());
|
||||
} else {
|
||||
G()->td_db()->get_binlog_pmc()->erase("proxy");
|
||||
}
|
||||
for (auto &child : children_) {
|
||||
child.second.reset();
|
||||
}
|
||||
@ -255,15 +364,47 @@ void ConnectionCreator::set_proxy_impl(Proxy proxy, bool from_db) {
|
||||
|
||||
get_proxy_info_query_token_ = 0;
|
||||
get_proxy_info_timestamp_ = Timestamp();
|
||||
if (!have_proxy || !from_db) {
|
||||
if (active_proxy_id_ == 0 || !from_db) {
|
||||
on_get_proxy_info(make_tl_object<telegram_api::help_proxyDataEmpty>(0));
|
||||
} else {
|
||||
schedule_get_proxy_info(0);
|
||||
}
|
||||
|
||||
loop();
|
||||
}
|
||||
|
||||
void ConnectionCreator::get_proxy(Promise<Proxy> promise) {
|
||||
promise.set_value(Proxy(proxy_));
|
||||
string ConnectionCreator::get_proxy_database_key(int32 proxy_id) {
|
||||
CHECK(proxy_id > 0);
|
||||
if (proxy_id == 1) {
|
||||
return "proxy";
|
||||
}
|
||||
return PSTRING() << "proxy" << proxy_id;
|
||||
}
|
||||
|
||||
string ConnectionCreator::get_proxy_used_database_key(int32 proxy_id) {
|
||||
CHECK(proxy_id > 0);
|
||||
return PSTRING() << "proxy_used" << proxy_id;
|
||||
}
|
||||
|
||||
td_api::object_ptr<td_api::proxy> ConnectionCreator::get_proxy_object(int32 proxy_id) const {
|
||||
auto it = proxies_.find(proxy_id);
|
||||
CHECK(it != proxies_.end());
|
||||
const Proxy &proxy = it->second;
|
||||
td_api::object_ptr<td_api::ProxyType> type;
|
||||
switch (proxy.type()) {
|
||||
case Proxy::Type::Socks5:
|
||||
type = make_tl_object<td_api::proxyTypeSocks5>(proxy.user().str(), proxy.password().str());
|
||||
break;
|
||||
case Proxy::Type::Mtproto:
|
||||
type = make_tl_object<td_api::proxyTypeMtproto>(proxy.secret().str());
|
||||
break;
|
||||
default:
|
||||
UNREACHABLE();
|
||||
}
|
||||
auto last_used_date_it = proxy_last_used_date_.find(proxy_id);
|
||||
auto last_used_date = last_used_date_it == proxy_last_used_date_.end() ? 0 : last_used_date_it->second;
|
||||
return make_tl_object<td_api::proxy>(proxy_id, proxy.server().str(), proxy.port(), last_used_date,
|
||||
proxy_id == active_proxy_id_, std::move(type));
|
||||
}
|
||||
|
||||
void ConnectionCreator::on_network(bool network_flag, uint32 network_generation) {
|
||||
@ -319,7 +460,7 @@ void ConnectionCreator::request_raw_connection(DcId dc_id, bool allow_media_only
|
||||
CHECK(client.allow_media_only == allow_media_only);
|
||||
CHECK(client.is_media == is_media);
|
||||
}
|
||||
VLOG(connections) << tag("client", format::as_hex(client.hash)) << " " << dc_id << " "
|
||||
VLOG(connections) << "Request connection for " << tag("client", format::as_hex(client.hash)) << " to " << dc_id << " "
|
||||
<< tag("allow_media_only", allow_media_only);
|
||||
client.queries.push_back(std::move(promise));
|
||||
|
||||
@ -346,8 +487,10 @@ void ConnectionCreator::client_loop(ClientInfo &client) {
|
||||
if (close_flag_) {
|
||||
return;
|
||||
}
|
||||
auto proxy_type = proxy_.type();
|
||||
bool use_proxy = proxy_type != Proxy::Type::None;
|
||||
|
||||
Proxy *proxy = active_proxy_id_ == 0 ? nullptr : &proxies_[active_proxy_id_];
|
||||
auto proxy_type = proxy == nullptr ? Proxy::Type::None : proxy->type();
|
||||
bool use_proxy = proxy != nullptr;
|
||||
bool use_socks5_proxy = proxy_type == Proxy::Type::Socks5;
|
||||
bool use_mtproto_proxy = proxy_type == Proxy::Type::Mtproto;
|
||||
if (use_proxy && !proxy_ip_address_.is_valid()) {
|
||||
@ -426,7 +569,7 @@ void ConnectionCreator::client_loop(ClientInfo &client) {
|
||||
TRY_RESULT(info, dc_options_set_.find_connection(dc_id, allow_media_only, use_proxy));
|
||||
stat = nullptr;
|
||||
int16 raw_dc_id = narrow_cast<int16>(info.option->is_media_only() ? -dc_id.get_raw_id() : dc_id.get_raw_id());
|
||||
TRY_RESULT(secret, hex_decode(proxy_.secret()));
|
||||
TRY_RESULT(secret, hex_decode(proxy->secret()));
|
||||
transport_type = {mtproto::TransportType::ObfuscatedTcp, raw_dc_id, std::move(secret)};
|
||||
|
||||
debug_str = PSTRING() << "Mtproto " << proxy_ip_address_ << " to DC" << raw_dc_id;
|
||||
@ -526,7 +669,7 @@ void ConnectionCreator::client_loop(ClientInfo &client) {
|
||||
LOG(INFO) << "Start socks5: " << debug_str;
|
||||
auto token = next_token();
|
||||
children_[token] = create_actor<Socks5>(
|
||||
"Socks5", std::move(socket_fd), mtproto_ip, proxy_.user().str(), proxy_.password().str(),
|
||||
"Socks5", std::move(socket_fd), mtproto_ip, proxy->user().str(), proxy->password().str(),
|
||||
std::make_unique<Callback>(std::move(promise), std::move(stats_callback)), create_reference(token));
|
||||
} else {
|
||||
ConnectionData data;
|
||||
@ -542,7 +685,8 @@ void ConnectionCreator::client_create_raw_connection(Result<ConnectionData> r_co
|
||||
string debug_str, uint32 network_generation) {
|
||||
auto promise = PromiseCreator::lambda([actor_id = actor_id(this), hash, check_mode,
|
||||
debug_str](Result<std::unique_ptr<mtproto::RawConnection>> result) mutable {
|
||||
VLOG(connections) << "Ready " << debug_str << " " << tag("checked", check_mode) << tag("ok", result.is_ok());
|
||||
VLOG(connections) << "Ready connection " << (check_mode ? "(" : "(un") << "checked) "
|
||||
<< (result.is_ok() ? result.ok().get() : nullptr) << " " << debug_str;
|
||||
send_closure(std::move(actor_id), &ConnectionCreator::client_add_connection, hash, std::move(result), check_mode);
|
||||
});
|
||||
|
||||
@ -588,6 +732,7 @@ void ConnectionCreator::client_add_connection(size_t hash,
|
||||
client.checking_connections--;
|
||||
}
|
||||
if (r_raw_connection.is_ok()) {
|
||||
VLOG(connections) << "Add ready connection " << r_raw_connection.ok().get() << " for " << tag("client", hash);
|
||||
client.backoff.clear();
|
||||
client.ready_connections.push_back(std::make_pair(r_raw_connection.move_as_ok(), Time::now_cached()));
|
||||
}
|
||||
@ -652,18 +797,59 @@ void ConnectionCreator::start_up() {
|
||||
on_dc_options(std::move(dc_options));
|
||||
}
|
||||
|
||||
Proxy proxy;
|
||||
auto log_event_proxy = G()->td_db()->get_binlog_pmc()->get("proxy");
|
||||
if (!log_event_proxy.empty()) {
|
||||
log_event_parse(proxy, log_event_proxy).ensure();
|
||||
auto proxy_info = G()->td_db()->get_binlog_pmc()->prefix_get("proxy");
|
||||
auto it = proxy_info.find("proxy_max_id");
|
||||
if (it != proxy_info.end()) {
|
||||
max_proxy_id_ = to_integer<int32>(it->second);
|
||||
proxy_info.erase(it);
|
||||
}
|
||||
it = proxy_info.find("proxy_active_id");
|
||||
if (it != proxy_info.end()) {
|
||||
active_proxy_id_ = to_integer<int32>(it->second);
|
||||
proxy_info.erase(it);
|
||||
}
|
||||
|
||||
for (auto &info : proxy_info) {
|
||||
if (begins_with(info.first, "proxy_used")) {
|
||||
int32 proxy_id = to_integer_safe<int32>(Slice(info.first).substr(10)).move_as_ok();
|
||||
int32 last_used = to_integer_safe<int32>(info.second).move_as_ok();
|
||||
proxy_last_used_date_[proxy_id] = last_used;
|
||||
} else {
|
||||
int32 proxy_id = info.first == "proxy" ? 1 : to_integer_safe<int32>(Slice(info.first).substr(5)).move_as_ok();
|
||||
CHECK(proxies_.count(proxy_id) == 0);
|
||||
log_event_parse(proxies_[proxy_id], info.second).ensure();
|
||||
}
|
||||
}
|
||||
|
||||
if (max_proxy_id_ == 0) {
|
||||
// legacy one-proxy version
|
||||
max_proxy_id_ = 2;
|
||||
if (!proxies_.empty()) {
|
||||
CHECK(proxies_.begin()->first == 1);
|
||||
active_proxy_id_ = 1;
|
||||
G()->td_db()->get_binlog_pmc()->set("proxy_active_id", "1");
|
||||
}
|
||||
G()->td_db()->get_binlog_pmc()->set("proxy_max_id", "2");
|
||||
} else if (max_proxy_id_ < 2) {
|
||||
LOG(ERROR) << "Found wrong max_proxy_id = " << max_proxy_id_;
|
||||
max_proxy_id_ = 2;
|
||||
}
|
||||
|
||||
if (active_proxy_id_ != 0) {
|
||||
if (proxies_[active_proxy_id_].type() == Proxy::Type::Mtproto) {
|
||||
G()->mtproto_header().set_proxy(proxies_[active_proxy_id_]);
|
||||
G()->net_query_dispatcher().update_mtproto_header();
|
||||
}
|
||||
|
||||
on_proxy_changed(true);
|
||||
}
|
||||
set_proxy_impl(std::move(proxy), true);
|
||||
|
||||
get_host_by_name_actor_ =
|
||||
create_actor_on_scheduler<GetHostByNameActor>("GetHostByNameActor", G()->get_gc_scheduler_id(), 5 * 60 - 1, 0);
|
||||
|
||||
ref_cnt_guard_ = create_reference(-1);
|
||||
|
||||
is_inited_ = true;
|
||||
loop();
|
||||
}
|
||||
|
||||
@ -730,12 +916,15 @@ DcOptions ConnectionCreator::get_default_dc_options(bool is_test) {
|
||||
}
|
||||
|
||||
void ConnectionCreator::loop() {
|
||||
if (!is_inited_) {
|
||||
return;
|
||||
}
|
||||
if (!network_flag_) {
|
||||
return;
|
||||
}
|
||||
|
||||
Timestamp timeout;
|
||||
if (proxy_.type() == Proxy::Type::Mtproto) {
|
||||
if (active_proxy_id_ != 0 && proxies_[active_proxy_id_].type() == Proxy::Type::Mtproto) {
|
||||
if (get_proxy_info_timestamp_.is_in_past()) {
|
||||
if (get_proxy_info_query_token_ == 0) {
|
||||
get_proxy_info_query_token_ = next_token();
|
||||
@ -749,12 +938,13 @@ void ConnectionCreator::loop() {
|
||||
}
|
||||
}
|
||||
|
||||
if (proxy_.type() != Proxy::Type::None) {
|
||||
if (active_proxy_id_ != 0) {
|
||||
if (resolve_proxy_timestamp_.is_in_past()) {
|
||||
if (resolve_proxy_query_token_ == 0) {
|
||||
resolve_proxy_query_token_ = next_token();
|
||||
const Proxy &proxy = proxies_[active_proxy_id_];
|
||||
send_closure(
|
||||
get_host_by_name_actor_, &GetHostByNameActor::run, proxy_.server().str(), proxy_.port(),
|
||||
get_host_by_name_actor_, &GetHostByNameActor::run, proxy.server().str(), proxy.port(),
|
||||
PromiseCreator::lambda([actor_id = create_reference(resolve_proxy_query_token_)](Result<IPAddress> result) {
|
||||
send_closure(std::move(actor_id), &ConnectionCreator::on_proxy_resolved, std::move(result), false);
|
||||
}));
|
||||
|
@ -47,40 +47,6 @@ namespace td {
|
||||
|
||||
class Proxy {
|
||||
public:
|
||||
tl_object_ptr<td_api::Proxy> as_td_api() const {
|
||||
switch (type_) {
|
||||
case Type::None:
|
||||
return make_tl_object<td_api::proxyEmpty>();
|
||||
case Type::Socks5:
|
||||
return make_tl_object<td_api::proxySocks5>(server_, port_, user_, password_);
|
||||
case Type::Mtproto:
|
||||
return make_tl_object<td_api::proxyMtproto>(server_, port_, secret_);
|
||||
}
|
||||
UNREACHABLE();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
static Proxy from_td_api(const tl_object_ptr<td_api::Proxy> &proxy) {
|
||||
if (proxy == nullptr) {
|
||||
return Proxy();
|
||||
}
|
||||
|
||||
switch (proxy->get_id()) {
|
||||
case td_api::proxyEmpty::ID:
|
||||
return Proxy();
|
||||
case td_api::proxySocks5::ID: {
|
||||
auto &socks5_proxy = static_cast<const td_api::proxySocks5 &>(*proxy);
|
||||
return Proxy::socks5(socks5_proxy.server_, socks5_proxy.port_, socks5_proxy.username_, socks5_proxy.password_);
|
||||
}
|
||||
case td_api::proxyMtproto::ID: {
|
||||
auto &mtproto_proxy = static_cast<const td_api::proxyMtproto &>(*proxy);
|
||||
return Proxy::mtproto(mtproto_proxy.server_, mtproto_proxy.port_, mtproto_proxy.secret_);
|
||||
}
|
||||
}
|
||||
UNREACHABLE();
|
||||
return Proxy();
|
||||
}
|
||||
|
||||
static Proxy socks5(string server, int32 port, string user, string password) {
|
||||
Proxy proxy;
|
||||
proxy.type_ = Type::Socks5;
|
||||
@ -165,8 +131,13 @@ class ConnectionCreator : public NetQueryCallback {
|
||||
void set_net_stats_callback(std::shared_ptr<NetStatsCallback> common_callback,
|
||||
std::shared_ptr<NetStatsCallback> media_callback);
|
||||
|
||||
void set_proxy(Proxy proxy);
|
||||
void get_proxy(Promise<Proxy> promise);
|
||||
void add_proxy(string server, int32 port, bool enable, td_api::object_ptr<td_api::ProxyType> proxy_type,
|
||||
Promise<td_api::object_ptr<td_api::proxy>> promise);
|
||||
void enable_proxy(int32 proxy_id, Promise<Unit> promise);
|
||||
void disable_proxy(Promise<Unit> promise);
|
||||
void remove_proxy(int32 proxy_id, Promise<Unit> promise);
|
||||
void get_proxies(Promise<td_api::object_ptr<td_api::proxies>> promise);
|
||||
void ping_proxy(int32 proxy_id, Promise<double> promise);
|
||||
|
||||
private:
|
||||
ActorShared<> parent_;
|
||||
@ -174,8 +145,12 @@ class ConnectionCreator : public NetQueryCallback {
|
||||
bool network_flag_ = false;
|
||||
uint32 network_generation_ = 0;
|
||||
bool online_flag_ = false;
|
||||
bool is_inited_ = false;
|
||||
|
||||
Proxy proxy_;
|
||||
std::map<int32, Proxy> proxies_;
|
||||
std::map<int32, int32> proxy_last_used_date_;
|
||||
int32 max_proxy_id_ = 0;
|
||||
int32 active_proxy_id_ = 0;
|
||||
ActorOwn<GetHostByNameActor> get_host_by_name_actor_;
|
||||
IPAddress proxy_ip_address_;
|
||||
Timestamp resolve_proxy_timestamp_;
|
||||
@ -243,7 +218,13 @@ class ConnectionCreator : public NetQueryCallback {
|
||||
uint64 next_token() {
|
||||
return ++current_token_;
|
||||
}
|
||||
void set_proxy_impl(Proxy proxy, bool from_db);
|
||||
|
||||
void enable_proxy_impl(int32 proxy_id);
|
||||
void disable_proxy_impl();
|
||||
void on_proxy_changed(bool from_db);
|
||||
static string get_proxy_database_key(int32 proxy_id);
|
||||
static string get_proxy_used_database_key(int32 proxy_id);
|
||||
td_api::object_ptr<td_api::proxy> get_proxy_object(int32 proxy_id) const;
|
||||
|
||||
void start_up() override;
|
||||
void hangup_shared() override;
|
||||
|
@ -37,6 +37,7 @@
|
||||
namespace td {
|
||||
|
||||
namespace detail {
|
||||
|
||||
class GenAuthKeyActor : public Actor {
|
||||
public:
|
||||
GenAuthKeyActor(std::unique_ptr<mtproto::AuthKeyHandshake> handshake,
|
||||
@ -83,13 +84,16 @@ class GenAuthKeyActor : public Actor {
|
||||
handshake_promise_.set_value(std::move(handshake_));
|
||||
return;
|
||||
}
|
||||
|
||||
auto raw_connection = r_raw_connection.move_as_ok();
|
||||
VLOG(dc) << "Receive raw connection " << raw_connection.get();
|
||||
network_generation_ = raw_connection->extra_;
|
||||
child_ = create_actor_on_scheduler<mtproto::HandshakeActor>(
|
||||
"HandshakeActor", G()->get_slow_net_scheduler_id(), std::move(handshake_), std::move(raw_connection),
|
||||
std::move(context_), 10, std::move(connection_promise_), std::move(handshake_promise_));
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
Session::Session(unique_ptr<Callback> callback, std::shared_ptr<AuthDataShared> shared_auth_data, bool is_main,
|
||||
@ -178,7 +182,7 @@ void Session::connection_online_update(bool force) {
|
||||
return;
|
||||
}
|
||||
connection_online_flag_ = new_connection_online_flag;
|
||||
LOG(INFO) << "Set connection_online " << connection_online_flag_;
|
||||
VLOG(dc) << "Set connection_online " << connection_online_flag_;
|
||||
if (is_main_) {
|
||||
if (main_connection_.connection) {
|
||||
main_connection_.connection->set_online(connection_online_flag_);
|
||||
@ -847,9 +851,10 @@ void Session::connection_open(ConnectionInfo *info, bool ask_info) {
|
||||
});
|
||||
|
||||
if (cached_connection_) {
|
||||
LOG(INFO) << "Reuse cached connection";
|
||||
VLOG(dc) << "Reuse cached connection";
|
||||
promise.set_value(std::move(cached_connection_));
|
||||
} else {
|
||||
VLOG(dc) << "Request new connection";
|
||||
callback_->request_raw_connection(std::move(promise));
|
||||
}
|
||||
|
||||
@ -857,7 +862,7 @@ void Session::connection_open(ConnectionInfo *info, bool ask_info) {
|
||||
}
|
||||
|
||||
void Session::connection_add(std::unique_ptr<mtproto::RawConnection> raw_connection) {
|
||||
LOG(INFO) << "Cache connection";
|
||||
VLOG(dc) << "Cache connection " << raw_connection.get();
|
||||
cached_connection_ = std::move(raw_connection);
|
||||
cached_connection_timestamp_ = Time::now();
|
||||
}
|
||||
@ -875,10 +880,10 @@ void Session::connection_check_mode(ConnectionInfo *info) {
|
||||
void Session::connection_open_finish(ConnectionInfo *info,
|
||||
Result<std::unique_ptr<mtproto::RawConnection>> r_raw_connection) {
|
||||
if (close_flag_ || info->state != ConnectionInfo::State::Connecting) {
|
||||
VLOG(dc) << "Ignore raw connection while closing";
|
||||
return;
|
||||
}
|
||||
current_info_ = info;
|
||||
// Create new connection
|
||||
if (r_raw_connection.is_error()) {
|
||||
LOG(WARNING) << "Failed to open socket: " << r_raw_connection.error();
|
||||
info->state = ConnectionInfo::State::Empty;
|
||||
@ -887,6 +892,7 @@ void Session::connection_open_finish(ConnectionInfo *info,
|
||||
}
|
||||
|
||||
auto raw_connection = r_raw_connection.move_as_ok();
|
||||
VLOG(dc) << "Receive raw connection " << raw_connection.get();
|
||||
if (raw_connection->extra_ != network_generation_) {
|
||||
LOG(WARNING) << "Got RawConnection with old network_generation";
|
||||
info->state = ConnectionInfo::State::Empty;
|
||||
@ -897,10 +903,10 @@ void Session::connection_open_finish(ConnectionInfo *info,
|
||||
Mode expected_mode =
|
||||
raw_connection->get_transport_type().type == mtproto::TransportType::Http ? Mode::Http : Mode::Tcp;
|
||||
if (mode_ != expected_mode) {
|
||||
LOG(INFO) << "Change mode " << mode_ << "--->" << expected_mode;
|
||||
VLOG(dc) << "Change mode " << mode_ << "--->" << expected_mode;
|
||||
mode_ = expected_mode;
|
||||
if (info->connection_id == 1 && mode_ != Mode::Http) {
|
||||
LOG(WARNING) << "Got tcp connection, for long poll connection";
|
||||
LOG(WARNING) << "Got tcp connection for long poll connection";
|
||||
connection_add(std::move(raw_connection));
|
||||
info->state = ConnectionInfo::State::Empty;
|
||||
yield();
|
||||
|
@ -409,7 +409,7 @@ void Scheduler::set_actor_timeout_in(ActorInfo *actor_info, double timeout) {
|
||||
|
||||
void Scheduler::set_actor_timeout_at(ActorInfo *actor_info, double timeout_at) {
|
||||
HeapNode *heap_node = actor_info->get_heap_node();
|
||||
VLOG(actor) << "set actor " << *actor_info << " " << tag("timeout", timeout_at) << timeout_at - Time::now_cached();
|
||||
VLOG(actor) << "Set actor " << *actor_info << " timeout in " << timeout_at - Time::now_cached();
|
||||
if (heap_node->in_heap()) {
|
||||
timeout_queue_.fix(timeout_at, heap_node);
|
||||
} else {
|
||||
|
Loading…
Reference in New Issue
Block a user