td_api: TestProxy query draft
GitOrigin-RevId: 67944e916813c6260df5be6cb4e77f7163854738
This commit is contained in:
parent
68bb65344b
commit
4079363f1a
@ -423,6 +423,7 @@ set(TDLIB_SOURCE
|
|||||||
td/telegram/net/NetQueryDelayer.cpp
|
td/telegram/net/NetQueryDelayer.cpp
|
||||||
td/telegram/net/NetQueryDispatcher.cpp
|
td/telegram/net/NetQueryDispatcher.cpp
|
||||||
td/telegram/net/NetStatsManager.cpp
|
td/telegram/net/NetStatsManager.cpp
|
||||||
|
td/telegram/net/Proxy.cpp
|
||||||
td/telegram/net/PublicRsaKeyShared.cpp
|
td/telegram/net/PublicRsaKeyShared.cpp
|
||||||
td/telegram/net/PublicRsaKeyWatchdog.cpp
|
td/telegram/net/PublicRsaKeyWatchdog.cpp
|
||||||
td/telegram/net/Session.cpp
|
td/telegram/net/Session.cpp
|
||||||
|
@ -3995,6 +3995,8 @@ testCallVectorStringObject x:vector<testString> = TestVectorStringObject;
|
|||||||
testSquareInt x:int32 = TestInt;
|
testSquareInt x:int32 = TestInt;
|
||||||
//@description Sends a simple network request to the Telegram servers; for testing only. Can be called before authorization
|
//@description Sends a simple network request to the Telegram servers; for testing only. Can be called before authorization
|
||||||
testNetwork = Ok;
|
testNetwork = Ok;
|
||||||
|
//@description Sends a simple network request to the Telegram servers via proxy; for testing only. Can be called before authorization @server Proxy ip @port Proxy port @type Proxy type
|
||||||
|
testProxy server:string port:int32 type:ProxyType = Ok;
|
||||||
//@description Forces an updates.getDifference call to the Telegram servers; for testing only
|
//@description Forces an updates.getDifference call to the Telegram servers; for testing only
|
||||||
testGetDifference = Ok;
|
testGetDifference = Ok;
|
||||||
//@description Does nothing and ensures that the Update object is used; for testing only. This is an offline method. Can be called before authorization
|
//@description Does nothing and ensures that the Update object is used; for testing only. This is an offline method. Can be called before authorization
|
||||||
|
Binary file not shown.
@ -50,6 +50,7 @@
|
|||||||
#include "td/telegram/net/NetQueryDispatcher.h"
|
#include "td/telegram/net/NetQueryDispatcher.h"
|
||||||
#include "td/telegram/net/NetStatsManager.h"
|
#include "td/telegram/net/NetStatsManager.h"
|
||||||
#include "td/telegram/net/NetType.h"
|
#include "td/telegram/net/NetType.h"
|
||||||
|
#include "td/telegram/net/Proxy.h"
|
||||||
#include "td/telegram/net/TempAuthKeyWatchdog.h"
|
#include "td/telegram/net/TempAuthKeyWatchdog.h"
|
||||||
#include "td/telegram/NotificationGroupId.h"
|
#include "td/telegram/NotificationGroupId.h"
|
||||||
#include "td/telegram/NotificationId.h"
|
#include "td/telegram/NotificationId.h"
|
||||||
@ -103,6 +104,10 @@
|
|||||||
#include "td/utils/tl_parsers.h"
|
#include "td/utils/tl_parsers.h"
|
||||||
#include "td/utils/utf8.h"
|
#include "td/utils/utf8.h"
|
||||||
|
|
||||||
|
#include "td/mtproto/HandshakeActor.h"
|
||||||
|
#include "td/mtproto/RawConnection.h"
|
||||||
|
#include "td/telegram/net/PublicRsaKeyShared.h"
|
||||||
|
|
||||||
#include <limits>
|
#include <limits>
|
||||||
#include <tuple>
|
#include <tuple>
|
||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
@ -539,6 +544,81 @@ class TestQuery : public Td::ResultHandler {
|
|||||||
private:
|
private:
|
||||||
uint64 request_id_;
|
uint64 request_id_;
|
||||||
};
|
};
|
||||||
|
class TestProxyRequest : public RequestActor<Unit> {
|
||||||
|
Proxy proxy_;
|
||||||
|
ActorOwn<> child_;
|
||||||
|
|
||||||
|
auto get_transport() {
|
||||||
|
return mtproto::TransportType{mtproto::TransportType::ObfuscatedTcp, 2, proxy_.secret()};
|
||||||
|
}
|
||||||
|
|
||||||
|
void do_run(Promise<Unit> &&promise) override {
|
||||||
|
if (get_tries() < 2) {
|
||||||
|
promise.set_value(Unit());
|
||||||
|
}
|
||||||
|
|
||||||
|
IPAddress ip;
|
||||||
|
auto status = ip.init_host_port(proxy_.server(), proxy_.port());
|
||||||
|
if (status.is_error()) {
|
||||||
|
return promise.set_error(std::move(status));
|
||||||
|
}
|
||||||
|
auto r_socket_fd = SocketFd::open(ip);
|
||||||
|
if (r_socket_fd.is_error()) {
|
||||||
|
return promise.set_error(r_socket_fd.move_as_error());
|
||||||
|
}
|
||||||
|
|
||||||
|
auto connection_promise = PromiseCreator::lambda(
|
||||||
|
[actor_id = actor_id(this), promise = std::move(promise)](Result<ConnectionCreator::ConnectionData> r) mutable {
|
||||||
|
send_closure(actor_id, &TestProxyRequest::on_connection_data, std::move(r), std::move(promise));
|
||||||
|
});
|
||||||
|
|
||||||
|
child_ = ConnectionCreator::prepare_connection(r_socket_fd.move_as_ok(), {&proxy_, ip}, get_transport(), "",
|
||||||
|
IPAddress(), nullptr, {}, false, std::move(connection_promise));
|
||||||
|
}
|
||||||
|
|
||||||
|
void on_connection_data(Result<ConnectionCreator::ConnectionData> r, Promise<Unit> &&promise) {
|
||||||
|
if (r.is_error()) {
|
||||||
|
return promise.set_error(r.move_as_error());
|
||||||
|
}
|
||||||
|
class HandshakeContext : public mtproto::AuthKeyHandshakeContext {
|
||||||
|
public:
|
||||||
|
DhCallback *get_dh_callback() override {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
PublicRsaKeyInterface *get_public_rsa_key_interface() override {
|
||||||
|
return &public_rsa_key;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
PublicRsaKeyShared public_rsa_key{DcId::empty(), false};
|
||||||
|
};
|
||||||
|
auto handshake = make_unique<mtproto::AuthKeyHandshake>(2, 0);
|
||||||
|
auto data = r.move_as_ok();
|
||||||
|
auto raw_connection = make_unique<mtproto::RawConnection>(std::move(data.socket_fd), get_transport(), nullptr);
|
||||||
|
child_ = create_actor<mtproto::HandshakeActor>(
|
||||||
|
"HandshakeActor", std::move(handshake), std::move(raw_connection), make_unique<HandshakeContext>(), 10.0,
|
||||||
|
PromiseCreator::lambda([](Result<unique_ptr<mtproto::RawConnection>> raw_connection) {}),
|
||||||
|
PromiseCreator::lambda(
|
||||||
|
[promise = std::move(promise)](Result<unique_ptr<mtproto::AuthKeyHandshake>> handshake) mutable {
|
||||||
|
if (handshake.is_error()) {
|
||||||
|
return promise.set_error(handshake.move_as_error());
|
||||||
|
}
|
||||||
|
promise.set_value(Unit());
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
void do_set_result(Unit &&result) override {
|
||||||
|
}
|
||||||
|
|
||||||
|
void do_send_result() override {
|
||||||
|
send_result(make_tl_object<td_api::ok>());
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
TestProxyRequest(ActorShared<Td> td, uint64 request_id, Proxy proxy)
|
||||||
|
: RequestActor(std::move(td), request_id), proxy_(std::move(proxy)) {
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
class GetAccountTtlRequest : public RequestActor<int32> {
|
class GetAccountTtlRequest : public RequestActor<int32> {
|
||||||
int32 account_ttl_;
|
int32 account_ttl_;
|
||||||
@ -3309,6 +3389,7 @@ bool Td::is_preinitialization_request(int32 id) {
|
|||||||
case td_api::testCallVectorIntObject::ID:
|
case td_api::testCallVectorIntObject::ID:
|
||||||
case td_api::testCallVectorString::ID:
|
case td_api::testCallVectorString::ID:
|
||||||
case td_api::testCallVectorStringObject::ID:
|
case td_api::testCallVectorStringObject::ID:
|
||||||
|
case td_api::testProxy::ID:
|
||||||
return true;
|
return true;
|
||||||
default:
|
default:
|
||||||
return false;
|
return false;
|
||||||
@ -7523,6 +7604,14 @@ void Td::on_request(uint64 id, td_api::testNetwork &request) {
|
|||||||
create_handler<TestQuery>(id)->send();
|
create_handler<TestQuery>(id)->send();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Td::on_request(uint64 id, td_api::testProxy &request) {
|
||||||
|
auto r_proxy = Proxy::from_td_api(std::move(request.server_), request.port_, std::move(request.type_));
|
||||||
|
if (r_proxy.is_error()) {
|
||||||
|
return send_error(id, r_proxy.move_as_error());
|
||||||
|
}
|
||||||
|
CREATE_REQUEST(TestProxyRequest, r_proxy.move_as_ok());
|
||||||
|
}
|
||||||
|
|
||||||
void Td::on_request(uint64 id, td_api::testGetDifference &request) {
|
void Td::on_request(uint64 id, td_api::testGetDifference &request) {
|
||||||
updates_manager_->get_difference("testGetDifference");
|
updates_manager_->get_difference("testGetDifference");
|
||||||
send_closure(actor_id(this), &Td::send_result, id, make_tl_object<td_api::ok>());
|
send_closure(actor_id(this), &Td::send_result, id, make_tl_object<td_api::ok>());
|
||||||
|
@ -1022,6 +1022,7 @@ class Td final : public NetQueryCallback {
|
|||||||
|
|
||||||
// test
|
// test
|
||||||
void on_request(uint64 id, td_api::testNetwork &request);
|
void on_request(uint64 id, td_api::testNetwork &request);
|
||||||
|
void on_request(uint64 id, td_api::testProxy &request);
|
||||||
void on_request(uint64 id, td_api::testGetDifference &request);
|
void on_request(uint64 id, td_api::testGetDifference &request);
|
||||||
void on_request(uint64 id, td_api::testUseUpdate &request);
|
void on_request(uint64 id, td_api::testUseUpdate &request);
|
||||||
void on_request(uint64 id, td_api::testUseError &request);
|
void on_request(uint64 id, td_api::testUseError &request);
|
||||||
|
@ -3589,7 +3589,7 @@ class CliClient final : public Actor {
|
|||||||
} else if (op == "rproxy") {
|
} else if (op == "rproxy") {
|
||||||
send_request(td_api::make_object<td_api::removeProxy>(as_proxy_id(args)));
|
send_request(td_api::make_object<td_api::removeProxy>(as_proxy_id(args)));
|
||||||
} else if (op == "aproxy" || op == "aeproxy" || op == "aeproxytcp" || op == "editproxy" || op == "editeproxy" ||
|
} else if (op == "aproxy" || op == "aeproxy" || op == "aeproxytcp" || op == "editproxy" || op == "editeproxy" ||
|
||||||
op == "editeproxytcp") {
|
op == "editeproxytcp" || op == "tproxy") {
|
||||||
string proxy_id;
|
string proxy_id;
|
||||||
string server;
|
string server;
|
||||||
string port;
|
string port;
|
||||||
@ -3615,6 +3615,8 @@ class CliClient final : public Actor {
|
|||||||
if (op[0] == 'e') {
|
if (op[0] == 'e') {
|
||||||
send_request(td_api::make_object<td_api::editProxy>(as_proxy_id(proxy_id), server, to_integer<int32>(port),
|
send_request(td_api::make_object<td_api::editProxy>(as_proxy_id(proxy_id), server, to_integer<int32>(port),
|
||||||
enable, std::move(type)));
|
enable, std::move(type)));
|
||||||
|
} else if (op == "tproxy") {
|
||||||
|
send_request(td_api::make_object<td_api::testProxy>(server, to_integer<int32>(port), std::move(type)));
|
||||||
} else {
|
} else {
|
||||||
send_request(td_api::make_object<td_api::addProxy>(server, to_integer<int32>(port), enable, std::move(type)));
|
send_request(td_api::make_object<td_api::addProxy>(server, to_integer<int32>(port), enable, std::move(type)));
|
||||||
}
|
}
|
||||||
|
@ -90,41 +90,6 @@ class StatsCallback final : public mtproto::RawConnection::StatsCallback {
|
|||||||
|
|
||||||
} // namespace detail
|
} // namespace detail
|
||||||
|
|
||||||
class ConnectionCreator::ProxyInfo {
|
|
||||||
public:
|
|
||||||
ProxyInfo(Proxy *proxy, IPAddress ip_address) : proxy_(proxy), ip_address_(std::move(ip_address)) {
|
|
||||||
}
|
|
||||||
bool use_proxy() const {
|
|
||||||
return proxy_ != nullptr;
|
|
||||||
}
|
|
||||||
Proxy::Type proxy_type() const {
|
|
||||||
return proxy_ == nullptr ? Proxy::Type::None : proxy_->type();
|
|
||||||
}
|
|
||||||
bool use_socks5_proxy() const {
|
|
||||||
return proxy_type() == Proxy::Type::Socks5;
|
|
||||||
}
|
|
||||||
bool use_http_tcp_proxy() const {
|
|
||||||
return proxy_type() == Proxy::Type::HttpTcp;
|
|
||||||
}
|
|
||||||
bool use_http_caching_proxy() const {
|
|
||||||
return proxy_type() == Proxy::Type::HttpCaching;
|
|
||||||
}
|
|
||||||
bool use_mtproto_proxy() const {
|
|
||||||
return proxy_type() == Proxy::Type::Mtproto;
|
|
||||||
}
|
|
||||||
const Proxy &proxy() const {
|
|
||||||
CHECK(use_proxy());
|
|
||||||
return *proxy_;
|
|
||||||
}
|
|
||||||
const IPAddress &ip_address() const {
|
|
||||||
return ip_address_;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
Proxy *proxy_;
|
|
||||||
IPAddress ip_address_;
|
|
||||||
};
|
|
||||||
|
|
||||||
ConnectionCreator::ClientInfo::ClientInfo() {
|
ConnectionCreator::ClientInfo::ClientInfo() {
|
||||||
flood_control.add_limit(1, 1);
|
flood_control.add_limit(1, 1);
|
||||||
flood_control.add_limit(4, 2);
|
flood_control.add_limit(4, 2);
|
||||||
@ -175,44 +140,11 @@ void ConnectionCreator::set_net_stats_callback(std::shared_ptr<NetStatsCallback>
|
|||||||
void ConnectionCreator::add_proxy(int32 old_proxy_id, string server, int32 port, bool enable,
|
void ConnectionCreator::add_proxy(int32 old_proxy_id, string server, int32 port, bool enable,
|
||||||
td_api::object_ptr<td_api::ProxyType> proxy_type,
|
td_api::object_ptr<td_api::ProxyType> proxy_type,
|
||||||
Promise<td_api::object_ptr<td_api::proxy>> promise) {
|
Promise<td_api::object_ptr<td_api::proxy>> promise) {
|
||||||
if (proxy_type == nullptr) {
|
auto r_proxy = Proxy::from_td_api(std::move(server), port, std::move(proxy_type));
|
||||||
return promise.set_error(Status::Error(400, "Proxy type should not be empty"));
|
if (r_proxy.is_error()) {
|
||||||
}
|
return promise.set_error(r_proxy.move_as_error());
|
||||||
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"));
|
|
||||||
}
|
|
||||||
|
|
||||||
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::proxyTypeHttp::ID: {
|
|
||||||
auto type = td_api::move_object_as<td_api::proxyTypeHttp>(proxy_type);
|
|
||||||
if (type->http_only_) {
|
|
||||||
new_proxy = Proxy::http_caching(server, port, type->username_, type->password_);
|
|
||||||
} else {
|
|
||||||
new_proxy = Proxy::http_tcp(server, port, type->username_, type->password_);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case td_api::proxyTypeMtproto::ID: {
|
|
||||||
auto type = td_api::move_object_as<td_api::proxyTypeMtproto>(proxy_type);
|
|
||||||
auto r_secret = mtproto::ProxySecret::from_link(type->secret_);
|
|
||||||
if (r_secret.is_error()) {
|
|
||||||
return promise.set_error(r_secret.move_as_error());
|
|
||||||
}
|
|
||||||
new_proxy = Proxy::mtproto(server, port, r_secret.move_as_ok());
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
UNREACHABLE();
|
|
||||||
}
|
}
|
||||||
|
auto new_proxy = r_proxy.move_as_ok();
|
||||||
if (old_proxy_id >= 0) {
|
if (old_proxy_id >= 0) {
|
||||||
if (proxies_.count(old_proxy_id) == 0) {
|
if (proxies_.count(old_proxy_id) == 0) {
|
||||||
return promise.set_error(Status::Error(400, "Proxy not found"));
|
return promise.set_error(Status::Error(400, "Proxy not found"));
|
||||||
@ -438,52 +370,21 @@ void ConnectionCreator::ping_proxy_resolved(int32 proxy_id, IPAddress ip_address
|
|||||||
|
|
||||||
auto secret = extra.transport_type.secret;
|
auto secret = extra.transport_type.secret;
|
||||||
|
|
||||||
auto socket_fd_promise =
|
auto connection_promise =
|
||||||
PromiseCreator::lambda([promise = std::move(promise), actor_id = actor_id(this),
|
PromiseCreator::lambda([promise = std::move(promise), actor_id = actor_id(this),
|
||||||
transport_type = std::move(extra.transport_type)](Result<SocketFd> r_socket_fd) mutable {
|
transport_type = extra.transport_type](Result<ConnectionData> r_connection_data) mutable {
|
||||||
if (r_socket_fd.is_error()) {
|
if (r_connection_data.is_error()) {
|
||||||
return promise.set_error(Status::Error(400, r_socket_fd.error().public_message()));
|
return promise.set_error(Status::Error(400, r_connection_data.error().public_message()));
|
||||||
}
|
}
|
||||||
send_closure(actor_id, &ConnectionCreator::ping_proxy_socket_fd, r_socket_fd.move_as_ok(),
|
send_closure(actor_id, &ConnectionCreator::ping_proxy_socket_fd, r_connection_data.move_as_ok().socket_fd,
|
||||||
std::move(transport_type), std::move(promise));
|
std::move(transport_type), std::move(promise));
|
||||||
});
|
});
|
||||||
CHECK(proxy.use_proxy());
|
CHECK(proxy.use_proxy());
|
||||||
if (proxy.use_socks5_proxy() || proxy.use_http_tcp_proxy() || secret.emulate_tls()) {
|
|
||||||
class Callback : public TransparentProxy::Callback {
|
|
||||||
public:
|
|
||||||
explicit Callback(Promise<SocketFd> promise) : promise_(std::move(promise)) {
|
|
||||||
}
|
|
||||||
void set_result(Result<SocketFd> result) override {
|
|
||||||
promise_.set_result(std::move(result));
|
|
||||||
}
|
|
||||||
void on_connected() override {
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
Promise<SocketFd> promise_;
|
|
||||||
};
|
|
||||||
auto callback = make_unique<Callback>(std::move(socket_fd_promise));
|
|
||||||
|
|
||||||
LOG(INFO) << "Start ping proxy: " << extra.debug_str;
|
|
||||||
auto token = next_token();
|
auto token = next_token();
|
||||||
if (proxy.use_socks5_proxy()) {
|
auto ref = prepare_connection(std::move(socket_fd), proxy, extra.transport_type, extra.debug_str, extra.mtproto_ip,
|
||||||
children_[token] = {
|
nullptr, create_reference(token), true, std::move(connection_promise));
|
||||||
false, create_actor<Socks5>("PingSocks5", std::move(socket_fd), extra.mtproto_ip, proxy.proxy().user().str(),
|
if (!ref.empty()) {
|
||||||
proxy.proxy().password().str(), std::move(callback), create_reference(token))};
|
children_[token] = {false, std::move(ref)};
|
||||||
} else if (proxy.use_http_tcp_proxy()) {
|
|
||||||
children_[token] = {false, create_actor<HttpProxy>("PingHttpProxy", std::move(socket_fd), extra.mtproto_ip,
|
|
||||||
proxy.proxy().user().str(), proxy.proxy().password().str(),
|
|
||||||
std::move(callback), create_reference(token))};
|
|
||||||
} else if (secret.emulate_tls()) {
|
|
||||||
children_[token] = {false, create_actor<mtproto::TlsInit>("PingTlsInit", std::move(socket_fd), extra.mtproto_ip,
|
|
||||||
secret.get_domain(), secret.get_proxy_secret().str(),
|
|
||||||
std::move(callback), create_reference(token),
|
|
||||||
G()->get_dns_time_difference())};
|
|
||||||
} else {
|
|
||||||
UNREACHABLE();
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
socket_fd_promise.set_value(std::move(socket_fd));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -726,17 +627,19 @@ void ConnectionCreator::request_raw_connection_by_ip(IPAddress ip_address, mtpro
|
|||||||
}
|
}
|
||||||
auto socket_fd = r_socket_fd.move_as_ok();
|
auto socket_fd = r_socket_fd.move_as_ok();
|
||||||
|
|
||||||
auto socket_fd_promise =
|
auto connection_promise = PromiseCreator::lambda(
|
||||||
PromiseCreator::lambda([promise = std::move(promise), actor_id = actor_id(this), transport_type,
|
[promise = std::move(promise), actor_id = actor_id(this), transport_type,
|
||||||
network_generation = network_generation_](Result<SocketFd> r_socket_fd) mutable {
|
network_generation = network_generation_](Result<ConnectionData> r_connection_data) mutable {
|
||||||
if (r_socket_fd.is_error()) {
|
if (r_connection_data.is_error()) {
|
||||||
return promise.set_error(Status::Error(400, r_socket_fd.error().public_message()));
|
return promise.set_error(Status::Error(400, r_connection_data.error().public_message()));
|
||||||
}
|
}
|
||||||
auto raw_connection = make_unique<mtproto::RawConnection>(r_socket_fd.move_as_ok(), transport_type, nullptr);
|
auto raw_connection =
|
||||||
|
make_unique<mtproto::RawConnection>(r_connection_data.move_as_ok().socket_fd, transport_type, nullptr);
|
||||||
raw_connection->extra_ = network_generation;
|
raw_connection->extra_ = network_generation;
|
||||||
promise.set_value(std::move(raw_connection));
|
promise.set_value(std::move(raw_connection));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
<<<<<<< HEAD
|
||||||
if (transport_type.secret.emulate_tls()) {
|
if (transport_type.secret.emulate_tls()) {
|
||||||
class Callback : public TransparentProxy::Callback {
|
class Callback : public TransparentProxy::Callback {
|
||||||
public:
|
public:
|
||||||
@ -762,6 +665,13 @@ void ConnectionCreator::request_raw_connection_by_ip(IPAddress ip_address, mtpro
|
|||||||
create_reference(token), G()->get_dns_time_difference())};
|
create_reference(token), G()->get_dns_time_difference())};
|
||||||
} else {
|
} else {
|
||||||
socket_fd_promise.set_value(std::move(socket_fd));
|
socket_fd_promise.set_value(std::move(socket_fd));
|
||||||
|
=======
|
||||||
|
auto token = next_token();
|
||||||
|
auto ref = prepare_connection(std::move(socket_fd), {nullptr, IPAddress()}, transport_type, "", IPAddress(), nullptr,
|
||||||
|
create_reference(token), true, std::move(connection_promise));
|
||||||
|
if (!ref.empty()) {
|
||||||
|
children_[token] = {false, std::move(ref)};
|
||||||
|
>>>>>>> td_api: TestProxy query draft
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -832,6 +742,82 @@ Result<SocketFd> ConnectionCreator::find_connection(const ProxyInfo &proxy, DcId
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ActorOwn<> ConnectionCreator::prepare_connection(SocketFd socket_fd, const ProxyInfo &proxy,
|
||||||
|
mtproto::TransportType transport_type, string debug_str,
|
||||||
|
IPAddress mtproto_ip,
|
||||||
|
unique_ptr<mtproto::RawConnection::StatsCallback> stats_callback,
|
||||||
|
ActorShared<> parent, bool use_connection_token,
|
||||||
|
Promise<ConnectionData> promise) {
|
||||||
|
if (proxy.use_socks5_proxy() || proxy.use_http_tcp_proxy() || transport_type.secret.emulate_tls()) {
|
||||||
|
VLOG(connections) << "In client_loop: create new transparent proxy connection " << debug_str;
|
||||||
|
class Callback : public TransparentProxy::Callback {
|
||||||
|
public:
|
||||||
|
explicit Callback(Promise<ConnectionData> promise,
|
||||||
|
unique_ptr<mtproto::RawConnection::StatsCallback> stats_callback, bool use_connection_token)
|
||||||
|
: promise_(std::move(promise))
|
||||||
|
, stats_callback_(std::move(stats_callback))
|
||||||
|
, use_connection_token_(use_connection_token) {
|
||||||
|
}
|
||||||
|
void set_result(Result<SocketFd> result) override {
|
||||||
|
if (result.is_error()) {
|
||||||
|
if (use_connection_token_) {
|
||||||
|
connection_token_ = StateManager::ConnectionToken();
|
||||||
|
}
|
||||||
|
if (was_connected_ && stats_callback_) {
|
||||||
|
stats_callback_->on_error();
|
||||||
|
}
|
||||||
|
promise_.set_error(result.move_as_error());
|
||||||
|
} else {
|
||||||
|
ConnectionData data;
|
||||||
|
data.socket_fd = result.move_as_ok();
|
||||||
|
data.connection_token = std::move(connection_token_);
|
||||||
|
data.stats_callback = std::move(stats_callback_);
|
||||||
|
promise_.set_value(std::move(data));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void on_connected() override {
|
||||||
|
if (use_connection_token_) {
|
||||||
|
connection_token_ = StateManager::connection_proxy(G()->state_manager());
|
||||||
|
}
|
||||||
|
was_connected_ = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
Promise<ConnectionData> promise_;
|
||||||
|
StateManager::ConnectionToken connection_token_;
|
||||||
|
bool was_connected_{false};
|
||||||
|
unique_ptr<mtproto::RawConnection::StatsCallback> stats_callback_;
|
||||||
|
bool use_connection_token_;
|
||||||
|
};
|
||||||
|
LOG(INFO) << "Start " << (proxy.use_socks5_proxy() ? "Socks5" : (proxy.use_http_tcp_proxy() ? "HTTP" : "Tls"))
|
||||||
|
<< ": " << debug_str;
|
||||||
|
auto callback = td::make_unique<Callback>(std::move(promise), std::move(stats_callback), use_connection_token);
|
||||||
|
if (proxy.use_socks5_proxy()) {
|
||||||
|
return ActorOwn<>(create_actor<Socks5>("Socks5", std::move(socket_fd), mtproto_ip, proxy.proxy().user().str(),
|
||||||
|
proxy.proxy().password().str(), std::move(callback), std::move(parent)));
|
||||||
|
} else if (proxy.use_http_tcp_proxy()) {
|
||||||
|
return ActorOwn<>(create_actor<HttpProxy>("HttpProxy", std::move(socket_fd), mtproto_ip,
|
||||||
|
proxy.proxy().user().str(), proxy.proxy().password().str(),
|
||||||
|
std::move(callback), std::move(parent)));
|
||||||
|
} else if (transport_type.secret.emulate_tls()) {
|
||||||
|
return ActorOwn<>(create_actor<mtproto::TlsInit>(
|
||||||
|
"TlsInit", std::move(socket_fd), mtproto_ip, transport_type.secret.get_domain(),
|
||||||
|
transport_type.secret.get_proxy_secret().str(), std::move(callback), std::move(parent),
|
||||||
|
G()->get_dns_time_difference()));
|
||||||
|
} else {
|
||||||
|
UNREACHABLE();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
VLOG(connections) << "In client_loop: create new direct connection " << debug_str;
|
||||||
|
|
||||||
|
ConnectionData data;
|
||||||
|
data.socket_fd = std::move(socket_fd);
|
||||||
|
data.stats_callback = std::move(stats_callback);
|
||||||
|
promise.set_result(std::move(data));
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void ConnectionCreator::client_loop(ClientInfo &client) {
|
void ConnectionCreator::client_loop(ClientInfo &client) {
|
||||||
CHECK(client.hash != 0);
|
CHECK(client.hash != 0);
|
||||||
if (!network_flag_) {
|
if (!network_flag_) {
|
||||||
@ -953,6 +939,7 @@ void ConnectionCreator::client_loop(ClientInfo &client) {
|
|||||||
auto stats_callback =
|
auto stats_callback =
|
||||||
td::make_unique<detail::StatsCallback>(client.is_media ? media_net_stats_callback_ : common_net_stats_callback_,
|
td::make_unique<detail::StatsCallback>(client.is_media ? media_net_stats_callback_ : common_net_stats_callback_,
|
||||||
actor_id(this), client.hash, extra.stat);
|
actor_id(this), client.hash, extra.stat);
|
||||||
|
<<<<<<< HEAD
|
||||||
|
|
||||||
if (proxy.use_socks5_proxy() || proxy.use_http_tcp_proxy() || secret.emulate_tls()) {
|
if (proxy.use_socks5_proxy() || proxy.use_http_tcp_proxy() || secret.emulate_tls()) {
|
||||||
VLOG(connections) << "In client_loop: create new transparent proxy connection " << extra.debug_str;
|
VLOG(connections) << "In client_loop: create new transparent proxy connection " << extra.debug_str;
|
||||||
@ -1014,6 +1001,13 @@ void ConnectionCreator::client_loop(ClientInfo &client) {
|
|||||||
data.socket_fd = std::move(socket_fd);
|
data.socket_fd = std::move(socket_fd);
|
||||||
data.stats_callback = std::move(stats_callback);
|
data.stats_callback = std::move(stats_callback);
|
||||||
promise.set_result(std::move(data));
|
promise.set_result(std::move(data));
|
||||||
|
=======
|
||||||
|
auto token = next_token();
|
||||||
|
auto ref = prepare_connection(std::move(socket_fd), proxy, extra.transport_type, extra.debug_str, extra.mtproto_ip,
|
||||||
|
std::move(stats_callback), create_reference(token), true, std::move(promise));
|
||||||
|
if (!ref.empty()) {
|
||||||
|
children_[token] = {true, std::move(ref)};
|
||||||
|
>>>>>>> td_api: TestProxy query draft
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -18,6 +18,7 @@
|
|||||||
|
|
||||||
#include "td/mtproto/AuthData.h"
|
#include "td/mtproto/AuthData.h"
|
||||||
#include "td/mtproto/TransportType.h"
|
#include "td/mtproto/TransportType.h"
|
||||||
|
#include "td/mtproto/RawConnection.h"
|
||||||
|
|
||||||
#include "td/net/NetStats.h"
|
#include "td/net/NetStats.h"
|
||||||
|
|
||||||
@ -83,6 +84,52 @@ class ConnectionCreator : public NetQueryCallback {
|
|||||||
void get_proxy_link(int32 proxy_id, Promise<string> promise);
|
void get_proxy_link(int32 proxy_id, Promise<string> promise);
|
||||||
void ping_proxy(int32 proxy_id, Promise<double> promise);
|
void ping_proxy(int32 proxy_id, Promise<double> promise);
|
||||||
|
|
||||||
|
struct ConnectionData {
|
||||||
|
SocketFd socket_fd;
|
||||||
|
StateManager::ConnectionToken connection_token;
|
||||||
|
unique_ptr<mtproto::RawConnection::StatsCallback> stats_callback;
|
||||||
|
};
|
||||||
|
class ProxyInfo {
|
||||||
|
public:
|
||||||
|
ProxyInfo(Proxy *proxy, IPAddress ip_address) : proxy_(proxy), ip_address_(std::move(ip_address)) {
|
||||||
|
}
|
||||||
|
bool use_proxy() const {
|
||||||
|
return proxy_ != nullptr;
|
||||||
|
}
|
||||||
|
Proxy::Type proxy_type() const {
|
||||||
|
return proxy_ == nullptr ? Proxy::Type::None : proxy_->type();
|
||||||
|
}
|
||||||
|
bool use_socks5_proxy() const {
|
||||||
|
return proxy_type() == Proxy::Type::Socks5;
|
||||||
|
}
|
||||||
|
bool use_http_tcp_proxy() const {
|
||||||
|
return proxy_type() == Proxy::Type::HttpTcp;
|
||||||
|
}
|
||||||
|
bool use_http_caching_proxy() const {
|
||||||
|
return proxy_type() == Proxy::Type::HttpCaching;
|
||||||
|
}
|
||||||
|
bool use_mtproto_proxy() const {
|
||||||
|
return proxy_type() == Proxy::Type::Mtproto;
|
||||||
|
}
|
||||||
|
const Proxy &proxy() const {
|
||||||
|
CHECK(use_proxy());
|
||||||
|
return *proxy_;
|
||||||
|
}
|
||||||
|
const IPAddress &ip_address() const {
|
||||||
|
return ip_address_;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
Proxy *proxy_;
|
||||||
|
IPAddress ip_address_;
|
||||||
|
};
|
||||||
|
|
||||||
|
static ActorOwn<> prepare_connection(SocketFd socket_fd, const ProxyInfo &proxy,
|
||||||
|
mtproto::TransportType transport_type, string debug_str, IPAddress mtproto_ip,
|
||||||
|
unique_ptr<mtproto::RawConnection::StatsCallback> stats_callback,
|
||||||
|
ActorShared<> parent, bool use_connection_token,
|
||||||
|
Promise<ConnectionData> promise);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ActorShared<> parent_;
|
ActorShared<> parent_;
|
||||||
DcOptionsSet dc_options_set_;
|
DcOptionsSet dc_options_set_;
|
||||||
@ -207,11 +254,6 @@ class ConnectionCreator : public NetQueryCallback {
|
|||||||
|
|
||||||
void client_wakeup(size_t hash);
|
void client_wakeup(size_t hash);
|
||||||
void client_loop(ClientInfo &client);
|
void client_loop(ClientInfo &client);
|
||||||
struct ConnectionData {
|
|
||||||
SocketFd socket_fd;
|
|
||||||
StateManager::ConnectionToken connection_token;
|
|
||||||
unique_ptr<detail::StatsCallback> stats_callback;
|
|
||||||
};
|
|
||||||
void client_create_raw_connection(Result<ConnectionData> r_connection_data, bool check_mode,
|
void client_create_raw_connection(Result<ConnectionData> r_connection_data, bool check_mode,
|
||||||
mtproto::TransportType transport_type, size_t hash, string debug_str,
|
mtproto::TransportType transport_type, size_t hash, string debug_str,
|
||||||
uint32 network_generation);
|
uint32 network_generation);
|
||||||
@ -234,7 +276,6 @@ class ConnectionCreator : public NetQueryCallback {
|
|||||||
IPAddress mtproto_ip;
|
IPAddress mtproto_ip;
|
||||||
bool check_mode{false};
|
bool check_mode{false};
|
||||||
};
|
};
|
||||||
class ProxyInfo;
|
|
||||||
|
|
||||||
static Result<mtproto::TransportType> get_transport_type(const ProxyInfo &proxy,
|
static Result<mtproto::TransportType> get_transport_type(const ProxyInfo &proxy,
|
||||||
const DcOptionsSet::ConnectionInfo &info);
|
const DcOptionsSet::ConnectionInfo &info);
|
||||||
|
48
td/telegram/net/Proxy.cpp
Normal file
48
td/telegram/net/Proxy.cpp
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
//
|
||||||
|
// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2019
|
||||||
|
//
|
||||||
|
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||||
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
//
|
||||||
|
#include "td/telegram/net/Proxy.h"
|
||||||
|
#include "td/telegram/td_api.h"
|
||||||
|
namespace td {
|
||||||
|
Result<Proxy> Proxy::from_td_api(string server, int port, td_api::object_ptr<td_api::ProxyType> proxy_type) {
|
||||||
|
if (proxy_type == nullptr) {
|
||||||
|
return Status::Error(400, "Proxy type should not be empty");
|
||||||
|
}
|
||||||
|
if (server.empty()) {
|
||||||
|
return Status::Error(400, "Server name can't be empty");
|
||||||
|
}
|
||||||
|
if (port <= 0 || port > 65535) {
|
||||||
|
return Status::Error(400, "Wrong port number");
|
||||||
|
}
|
||||||
|
|
||||||
|
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::proxyTypeHttp::ID: {
|
||||||
|
auto type = td_api::move_object_as<td_api::proxyTypeHttp>(proxy_type);
|
||||||
|
if (type->http_only_) {
|
||||||
|
new_proxy = Proxy::http_caching(server, port, type->username_, type->password_);
|
||||||
|
} else {
|
||||||
|
new_proxy = Proxy::http_tcp(server, port, type->username_, type->password_);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case td_api::proxyTypeMtproto::ID: {
|
||||||
|
auto type = td_api::move_object_as<td_api::proxyTypeMtproto>(proxy_type);
|
||||||
|
TRY_RESULT(secret, mtproto::ProxySecret::from_link(type->secret_));
|
||||||
|
new_proxy = Proxy::mtproto(server, port, secret);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
UNREACHABLE();
|
||||||
|
}
|
||||||
|
return new_proxy;
|
||||||
|
}
|
||||||
|
} // namespace td
|
@ -13,10 +13,18 @@
|
|||||||
#include "td/utils/StringBuilder.h"
|
#include "td/utils/StringBuilder.h"
|
||||||
#include "td/utils/tl_helpers.h"
|
#include "td/utils/tl_helpers.h"
|
||||||
|
|
||||||
|
#include "td/tl/TlObject.h"
|
||||||
|
|
||||||
namespace td {
|
namespace td {
|
||||||
|
|
||||||
|
namespace td_api {
|
||||||
|
class ProxyType;
|
||||||
|
}
|
||||||
|
|
||||||
class Proxy {
|
class Proxy {
|
||||||
public:
|
public:
|
||||||
|
static Result<Proxy> from_td_api(string server, int port, tl_object_ptr<td_api::ProxyType> proxy_type);
|
||||||
|
|
||||||
static Proxy socks5(string server, int32 port, string user, string password) {
|
static Proxy socks5(string server, int32 port, string user, string password) {
|
||||||
Proxy proxy;
|
Proxy proxy;
|
||||||
proxy.type_ = Type::Socks5;
|
proxy.type_ = Type::Socks5;
|
||||||
|
Loading…
Reference in New Issue
Block a user