ConfigRecoverer: support tls obfuscation (not tested)

GitOrigin-RevId: edc982ee6d1ce2834a80464a7b20ef712f465814
This commit is contained in:
Arseny Smirnov 2019-07-09 16:45:38 +02:00
parent b9e5ebd222
commit 3a9ec3fc29
3 changed files with 51 additions and 16 deletions

View File

@ -197,11 +197,11 @@ ActorOwn<> get_simple_config_google_dns(Promise<SimpleConfig> promise, const Con
#endif
}
ActorOwn<> get_full_config(DcId dc_id, IPAddress ip_address, Promise<FullConfig> promise) {
ActorOwn<> get_full_config(DcId dc_id, IPAddress ip_address, mtproto::ProxySecret secret, Promise<FullConfig> promise) {
class SessionCallback : public Session::Callback {
public:
SessionCallback(ActorShared<> parent, IPAddress address)
: parent_(std::move(parent)), address_(std::move(address)) {
SessionCallback(ActorShared<> parent, IPAddress address, mtproto::ProxySecret secret)
: parent_(std::move(parent)), address_(std::move(address)), secret_(std::move(secret)) {
}
void on_failed() final {
}
@ -213,7 +213,7 @@ ActorOwn<> get_full_config(DcId dc_id, IPAddress ip_address, Promise<FullConfig>
VLOG(config_recoverer) << "Request full config from " << address_ << ", try = " << request_raw_connection_cnt_;
if (request_raw_connection_cnt_ <= 2) {
send_closure(G()->connection_creator(), &ConnectionCreator::request_raw_connection_by_ip, address_,
std::move(promise));
mtproto::TransportType{mtproto::TransportType::ObfuscatedTcp, 0, secret_}, std::move(promise));
} else {
// Delay all queries except first forever
delay_forever_.push_back(std::move(promise));
@ -229,6 +229,7 @@ ActorOwn<> get_full_config(DcId dc_id, IPAddress ip_address, Promise<FullConfig>
private:
ActorShared<> parent_;
IPAddress address_;
mtproto::ProxySecret secret_;
size_t request_raw_connection_cnt_{0};
std::vector<Promise<unique_ptr<mtproto::RawConnection>>> delay_forever_;
};
@ -309,13 +310,14 @@ ActorOwn<> get_full_config(DcId dc_id, IPAddress ip_address, Promise<FullConfig>
class GetConfigActor : public NetQueryCallback {
public:
GetConfigActor(DcId dc_id, IPAddress ip_address, Promise<FullConfig> promise)
: dc_id_(dc_id), ip_address_(std::move(ip_address)), promise_(std::move(promise)) {
GetConfigActor(DcId dc_id, IPAddress ip_address, mtproto::ProxySecret secret, Promise<FullConfig> promise)
: dc_id_(dc_id), ip_address_(std::move(ip_address)), secret_(std::move(secret)), promise_(std::move(promise)) {
}
private:
void start_up() override {
auto session_callback = make_unique<SessionCallback>(actor_shared(this, 1), std::move(ip_address_));
auto session_callback =
make_unique<SessionCallback>(actor_shared(this, 1), std::move(ip_address_), std::move(secret_));
auto auth_data = std::make_shared<SimpleAuthData>(dc_id_);
int32 int_dc_id = dc_id_.get_raw_id();
@ -357,10 +359,12 @@ ActorOwn<> get_full_config(DcId dc_id, IPAddress ip_address, Promise<FullConfig>
DcId dc_id_;
IPAddress ip_address_;
ActorOwn<Session> session_;
mtproto::ProxySecret secret_;
Promise<FullConfig> promise_;
};
return ActorOwn<>(create_actor<GetConfigActor>("GetConfigActor", dc_id, std::move(ip_address), std::move(promise)));
return ActorOwn<>(create_actor<GetConfigActor>("GetConfigActor", dc_id, std::move(ip_address), std::move(secret),
std::move(promise)));
}
class ConfigRecoverer : public Actor {
@ -611,6 +615,7 @@ class ConfigRecoverer : public Actor {
VLOG(config_recoverer) << "ASK FULL CONFIG";
full_config_query_ = get_full_config(
dc_options_.dc_options[dc_options_i_].get_dc_id(), dc_options_.dc_options[dc_options_i_].get_ip_address(),
dc_options_.dc_options[dc_options_i_].get_secret(),
PromiseCreator::lambda([actor_id = actor_shared(this)](Result<FullConfig> r_full_config) {
send_closure(actor_id, &ConfigRecoverer::on_full_config, std::move(r_full_config), false);
}));

View File

@ -718,19 +718,48 @@ void ConnectionCreator::request_raw_connection(DcId dc_id, bool allow_media_only
client_loop(client);
}
void ConnectionCreator::request_raw_connection_by_ip(IPAddress ip_address,
void ConnectionCreator::request_raw_connection_by_ip(IPAddress ip_address, mtproto::TransportType transport_type,
Promise<unique_ptr<mtproto::RawConnection>> promise) {
auto r_socket_fd = SocketFd::open(ip_address);
if (r_socket_fd.is_error()) {
return promise.set_error(r_socket_fd.move_as_error());
}
auto socket_fd = r_socket_fd.move_as_ok();
// TODO TransportType is wrong
auto raw_connection = make_unique<mtproto::RawConnection>(
r_socket_fd.move_as_ok(),
mtproto::TransportType{mtproto::TransportType::ObfuscatedTcp, 0, mtproto::ProxySecret()}, nullptr);
raw_connection->extra_ = network_generation_;
promise.set_value(std::move(raw_connection));
auto socket_fd_promise =
PromiseCreator::lambda([promise = std::move(promise), actor_id = actor_id(this), transport_type,
network_generation = network_generation_](Result<SocketFd> r_socket_fd) mutable {
if (r_socket_fd.is_error()) {
return promise.set_error(Status::Error(400, r_socket_fd.error().public_message()));
}
auto raw_connection = make_unique<mtproto::RawConnection>(r_socket_fd.move_as_ok(), transport_type, nullptr);
raw_connection->extra_ = network_generation;
promise.set_value(std::move(raw_connection));
});
if (transport_type.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 token = next_token();
auto callback = td::make_unique<Callback>(std::move(socket_fd_promise));
children_[token] = {false, create_actor<mtproto::TlsInit>(
"TlsInit", std::move(socket_fd), ip_address, transport_type.secret.get_domain(),
transport_type.secret.get_proxy_secret().str(), std::move(callback),
create_reference(token), G()->get_dns_time_difference())};
} else {
socket_fd_promise.set_value(std::move(socket_fd));
}
}
Result<mtproto::TransportType> ConnectionCreator::get_transport_type(const ProxyInfo &proxy,

View File

@ -68,7 +68,8 @@ class ConnectionCreator : public NetQueryCallback {
void request_raw_connection(DcId dc_id, bool allow_media_only, bool is_media,
Promise<unique_ptr<mtproto::RawConnection>> promise, size_t hash = 0,
unique_ptr<mtproto::AuthData> auth_data = {});
void request_raw_connection_by_ip(IPAddress ip_address, Promise<unique_ptr<mtproto::RawConnection>> promise);
void request_raw_connection_by_ip(IPAddress ip_address, mtproto::TransportType transport_type,
Promise<unique_ptr<mtproto::RawConnection>> promise);
void set_net_stats_callback(std::shared_ptr<NetStatsCallback> common_callback,
std::shared_ptr<NetStatsCallback> media_callback);