Add proxyMtproto to td_api.

GitOrigin-RevId: c872c063bc6e5d94c80ac1daa6b916f8ce5f4c23
This commit is contained in:
levlam 2018-05-08 17:48:30 +03:00
parent 63695490e0
commit 98289b9963
7 changed files with 84 additions and 30 deletions

View File

@ -2001,6 +2001,9 @@ proxyEmpty = Proxy;
//@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 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 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
inputSticker png_sticker:InputFile emojis:string mask_position:maskPosition = InputSticker;

Binary file not shown.

View File

@ -3062,9 +3062,13 @@ class CliClient final : public Actor {
std::tie(server, args) = split(args);
std::tie(port, args) = split(args);
std::tie(user, password) = split(args);
send_request(make_tl_object<td_api::setProxy>(
make_tl_object<td_api::proxySocks5>(server, to_integer<int32>(port), user, password)));
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)));
} else {
send_request(make_tl_object<td_api::setProxy>(
make_tl_object<td_api::proxySocks5>(server, to_integer<int32>(port), user, password)));
}
} else if (op == "gproxy") {
send_request(make_tl_object<td_api::getProxy>());
} else if (op == "touch") {

View File

@ -49,10 +49,14 @@ class StatsCallback final : public mtproto::RawConnection::StatsCallback {
}
void on_pong() final {
send_lambda(connection_creator_, [stat = option_stat_] { stat->on_ok(); });
if (option_stat_) {
send_lambda(connection_creator_, [stat = option_stat_] { stat->on_ok(); });
}
}
void on_error() final {
send_lambda(connection_creator_, [stat = option_stat_] { stat->on_error(); });
if (option_stat_) {
send_lambda(connection_creator_, [stat = option_stat_] { stat->on_error(); });
}
}
void on_mtproto_error() final {
@ -150,6 +154,10 @@ void Proxy::parse(T &parser) {
parse(port_, parser);
parse(user_, parser);
parse(password_, parser);
} else if (type_ == Proxy::Type::Mtproto) {
parse(server_, parser);
parse(port_, parser);
parse(secret_, parser);
} else {
CHECK(type_ == Proxy::Type::None);
}
@ -164,6 +172,10 @@ void Proxy::store(T &storer) const {
store(port_, storer);
store(user_, storer);
store(password_, storer);
} else if (type_ == Proxy::Type::Mtproto) {
store(server_, storer);
store(port_, storer);
store(secret_, storer);
} else {
CHECK(type_ == Proxy::Type::None);
}
@ -304,8 +316,11 @@ void ConnectionCreator::client_loop(ClientInfo &client) {
if (close_flag_) {
return;
}
bool use_socks5 = proxy_.type() == Proxy::Type::Socks5;
if (use_socks5 && !proxy_ip_address_.is_valid()) {
auto proxy_type = proxy_.type();
bool use_proxy = proxy_type != Proxy::Type::None;
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()) {
return;
}
@ -335,7 +350,7 @@ void ConnectionCreator::client_loop(ClientInfo &client) {
}
// Main loop. Create new connections till needed
bool check_mode = client.checking_connections != 0;
bool check_mode = client.checking_connections != 0 && !use_proxy;
while (true) {
// Check if we need new connections
if (client.queries.empty()) {
@ -377,7 +392,18 @@ void ConnectionCreator::client_loop(ClientInfo &client) {
// sync part
auto r_socket_fd = [&, dc_id = client.dc_id, allow_media_only = client.allow_media_only]() -> Result<SocketFd> {
TRY_RESULT(info, dc_options_set_.find_connection(dc_id, allow_media_only, use_socks5));
if (use_mtproto_proxy) {
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());
transport_type = {mtproto::TransportType::ObfuscatedTcp, raw_dc_id, proxy_.secret().str()};
debug_str = PSTRING() << "Mtproto " << proxy_ip_address_ << " to DC" << raw_dc_id;
LOG(INFO) << "Create: " << debug_str;
return SocketFd::open(proxy_ip_address_);
}
TRY_RESULT(info, dc_options_set_.find_connection(dc_id, allow_media_only, use_proxy));
stat = info.stat;
if (info.use_http) {
transport_type = {mtproto::TransportType::Http, 0, ""};
@ -387,16 +413,14 @@ void ConnectionCreator::client_loop(ClientInfo &client) {
}
check_mode |= info.should_check;
if (use_socks5) {
if (use_socks5_proxy) {
mtproto_ip = info.option->get_ip_address();
IPAddress socks5_ip;
TRY_STATUS(socks5_ip.init_host_port(proxy_.server(), proxy_.port()));
debug_str = PSTRING() << "Sock5 " << socks5_ip << " --> " << info.option->get_ip_address() << " " << dc_id
<< (info.use_http ? " HTTP" : "");
debug_str = PSTRING() << "Sock5 " << proxy_ip_address_ << " --> " << mtproto_ip << " " << dc_id;
LOG(INFO) << "Create: " << debug_str;
return SocketFd::open(socks5_ip);
return SocketFd::open(proxy_ip_address_);
} else {
debug_str = PSTRING() << info.option->get_ip_address() << " " << dc_id << (info.use_http ? " HTTP" : "");
debug_str = PSTRING() << info.option->get_ip_address() << " " << dc_id << (info.use_http ? " HTTP" : "")
<< (info.option->is_media_only() ? " MEDIA" : "");
LOG(INFO) << "Create: " << debug_str;
return SocketFd::open(info.option->get_ip_address());
}
@ -413,14 +437,16 @@ void ConnectionCreator::client_loop(ClientInfo &client) {
IPAddress debug_ip;
auto debug_ip_status = debug_ip.init_socket_address(socket_fd);
if (debug_ip_status.is_ok()) {
debug_str = PSTRING() << debug_str << debug_ip;
debug_str = PSTRING() << debug_str << " from " << debug_ip;
} else {
LOG(ERROR) << debug_ip_status;
}
client.pending_connections++;
if (check_mode) {
stat->on_check();
if (stat) {
stat->on_check();
}
client.checking_connections++;
}
@ -434,7 +460,7 @@ void ConnectionCreator::client_loop(ClientInfo &client) {
auto stats_callback = std::make_unique<detail::StatsCallback>(
client.is_media ? media_net_stats_callback_ : common_net_stats_callback_, actor_id(this), client.hash, stat);
if (use_socks5) {
if (use_socks5_proxy) {
class Callback : public Socks5::Callback {
public:
explicit Callback(Promise<ConnectionData> promise, std::unique_ptr<detail::StatsCallback> stats_callback)
@ -675,7 +701,7 @@ void ConnectionCreator::loop() {
if (!network_flag_) {
return;
}
if (proxy_.type() != Proxy::Type::Socks5) {
if (proxy_.type() == Proxy::Type::None) {
return;
}
if (resolve_proxy_query_token_ != 0) {
@ -702,11 +728,12 @@ void ConnectionCreator::on_proxy_resolved(Result<IPAddress> r_ip_address, bool d
}
resolve_proxy_query_token_ = 0;
if (r_ip_address.is_error()) {
resolve_proxy_timestamp_ = Timestamp::in(5 * 60);
resolve_proxy_timestamp_ = Timestamp::in(1 * 60);
return;
}
proxy_ip_address_ = r_ip_address.move_as_ok();
resolve_proxy_timestamp_ = Timestamp::in(29 * 60);
proxy_ip_address_.set_port(proxy_.port());
resolve_proxy_timestamp_ = Timestamp::in(5 * 60);
for (auto &client : clients_) {
client_loop(client.second);
}

View File

@ -52,6 +52,8 @@ class Proxy {
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;
@ -69,6 +71,10 @@ class Proxy {
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();
@ -84,6 +90,15 @@ class Proxy {
return proxy;
}
static Proxy mtproto(string server, int32 port, string secret) {
Proxy proxy;
proxy.type_ = Type::Mtproto;
proxy.server_ = std::move(server);
proxy.port_ = std::move(port);
proxy.secret_ = std::move(secret);
return proxy;
}
CSlice server() const {
return server_;
}
@ -100,7 +115,11 @@ class Proxy {
return password_;
}
enum class Type : int32 { None, Socks5 };
CSlice secret() const {
return secret_;
}
enum class Type : int32 { None, Socks5, Mtproto };
Type type() const {
return type_;
}
@ -117,11 +136,12 @@ class Proxy {
int32 port_ = 0;
string user_;
string password_;
string secret_;
};
inline bool operator==(const Proxy &lhs, const Proxy &rhs) {
return lhs.type() == rhs.type() && lhs.server() == rhs.server() && lhs.port() == rhs.port() &&
lhs.user() == rhs.user() && lhs.password() == rhs.password();
lhs.user() == rhs.user() && lhs.password() == rhs.password() && lhs.secret() == rhs.secret();
}
inline bool operator!=(const Proxy &lhs, const Proxy &rhs) {

View File

@ -28,11 +28,9 @@ class HeaderStorer {
// system_lang_code:string lang_pack:string lang_code:string proxy:flags.0?InputClientProxy query:!X = X;
store(static_cast<int32>(0x785188b8), storer);
int32 flags = 0;
/*
if (!is_anonymous && proxy.type() == Proxy::Type::Mtproto) {
if (!is_anonymous && options.proxy.type() == Proxy::Type::Mtproto) {
flags |= 1 << 0;
}
*/
store(flags, storer);
store(options.api_id, storer);
if (is_anonymous) {
@ -47,7 +45,10 @@ class HeaderStorer {
store(string(), storer);
store(string(), storer);
if ((flags & 1) != 0) {
// TODO
// inputClientProxy#75588b3f address:string port:int = InputClientProxy;
store(static_cast<int32>(0x75588b3f), storer);
store(Slice(options.proxy.server()), storer);
store(options.proxy.port(), storer);
}
}

View File

@ -6,7 +6,6 @@
//
#include "td/net/Socks5.h"
#include "td/utils/format.h"
#include "td/utils/logging.h"
#include "td/utils/misc.h"
#include "td/utils/port/Fd.h"
@ -183,7 +182,7 @@ Status Socks5::wait_ip_address_response() {
}
it.advance(1, c_slice);
if (c != '\0') {
return Status::Error(PSLICE() << tag("code", c));
return Status::Error(PSLICE() << "Receive error code " << static_cast<int32>(c) << " from server");
}
it.advance(1, c_slice);
if (c != '\0') {