Don't use implicitly namespace td in MTProto tests.
This commit is contained in:
parent
687193c8e9
commit
c2a2cb0055
423
test/mtproto.cpp
423
test/mtproto.cpp
@ -46,22 +46,20 @@
|
||||
#include "td/utils/tests.h"
|
||||
#include "td/utils/Time.h"
|
||||
|
||||
using namespace td;
|
||||
|
||||
TEST(Mtproto, GetHostByNameActor) {
|
||||
ConcurrentScheduler sched;
|
||||
td::ConcurrentScheduler sched;
|
||||
int threads_n = 1;
|
||||
sched.init(threads_n);
|
||||
|
||||
int cnt = 1;
|
||||
vector<ActorOwn<GetHostByNameActor>> actors;
|
||||
td::vector<td::ActorOwn<td::GetHostByNameActor>> actors;
|
||||
{
|
||||
auto guard = sched.get_main_guard();
|
||||
|
||||
auto run = [&](ActorId<GetHostByNameActor> actor_id, string host, bool prefer_ipv6, bool allow_ok,
|
||||
auto run = [&](td::ActorId<td::GetHostByNameActor> actor_id, td::string host, bool prefer_ipv6, bool allow_ok,
|
||||
bool allow_error) {
|
||||
auto promise = PromiseCreator::lambda([&cnt, &actors, num = cnt, host, allow_ok,
|
||||
allow_error](Result<IPAddress> r_ip_address) {
|
||||
auto promise = td::PromiseCreator::lambda([&cnt, &actors, num = cnt, host, allow_ok,
|
||||
allow_error](td::Result<td::IPAddress> r_ip_address) {
|
||||
if (r_ip_address.is_error() && !allow_error) {
|
||||
LOG(ERROR) << num << " \"" << host << "\" " << r_ip_address.error();
|
||||
}
|
||||
@ -70,41 +68,42 @@ TEST(Mtproto, GetHostByNameActor) {
|
||||
}
|
||||
if (--cnt == 0) {
|
||||
actors.clear();
|
||||
Scheduler::instance()->finish();
|
||||
td::Scheduler::instance()->finish();
|
||||
}
|
||||
});
|
||||
cnt++;
|
||||
send_closure_later(actor_id, &GetHostByNameActor::run, host, 443, prefer_ipv6, std::move(promise));
|
||||
td::send_closure_later(actor_id, &td::GetHostByNameActor::run, host, 443, prefer_ipv6, std::move(promise));
|
||||
};
|
||||
|
||||
std::vector<std::string> hosts = {"127.0.0.2",
|
||||
"1.1.1.1",
|
||||
"localhost",
|
||||
"web.telegram.org",
|
||||
"web.telegram.org.",
|
||||
"москва.рф",
|
||||
"",
|
||||
"%",
|
||||
" ",
|
||||
"a",
|
||||
"\x80",
|
||||
"[]",
|
||||
"127.0.0.1.",
|
||||
"0x12.0x34.0x56.0x78",
|
||||
"0x7f.001",
|
||||
"2001:0db8:85a3:0000:0000:8a2e:0370:7334",
|
||||
"[2001:0db8:85a3:0000:0000:8a2e:0370:7334]",
|
||||
"[[2001:0db8:85a3:0000:0000:8a2e:0370:7334]]"};
|
||||
for (const auto &types : {vector<GetHostByNameActor::ResolverType>{GetHostByNameActor::ResolverType::Native},
|
||||
vector<GetHostByNameActor::ResolverType>{GetHostByNameActor::ResolverType::Google},
|
||||
vector<GetHostByNameActor::ResolverType>{GetHostByNameActor::ResolverType::Google,
|
||||
GetHostByNameActor::ResolverType::Google,
|
||||
GetHostByNameActor::ResolverType::Native}}) {
|
||||
GetHostByNameActor::Options options;
|
||||
td::vector<td::string> hosts = {"127.0.0.2",
|
||||
"1.1.1.1",
|
||||
"localhost",
|
||||
"web.telegram.org",
|
||||
"web.telegram.org.",
|
||||
"москва.рф",
|
||||
"",
|
||||
"%",
|
||||
" ",
|
||||
"a",
|
||||
"\x80",
|
||||
"[]",
|
||||
"127.0.0.1.",
|
||||
"0x12.0x34.0x56.0x78",
|
||||
"0x7f.001",
|
||||
"2001:0db8:85a3:0000:0000:8a2e:0370:7334",
|
||||
"[2001:0db8:85a3:0000:0000:8a2e:0370:7334]",
|
||||
"[[2001:0db8:85a3:0000:0000:8a2e:0370:7334]]"};
|
||||
for (const auto &types :
|
||||
{td::vector<td::GetHostByNameActor::ResolverType>{td::GetHostByNameActor::ResolverType::Native},
|
||||
td::vector<td::GetHostByNameActor::ResolverType>{td::GetHostByNameActor::ResolverType::Google},
|
||||
td::vector<td::GetHostByNameActor::ResolverType>{td::GetHostByNameActor::ResolverType::Google,
|
||||
td::GetHostByNameActor::ResolverType::Google,
|
||||
td::GetHostByNameActor::ResolverType::Native}}) {
|
||||
td::GetHostByNameActor::Options options;
|
||||
options.resolver_types = types;
|
||||
options.scheduler_id = threads_n;
|
||||
|
||||
auto actor = create_actor<GetHostByNameActor>("GetHostByNameActor", std::move(options));
|
||||
auto actor = td::create_actor<td::GetHostByNameActor>("GetHostByNameActor", std::move(options));
|
||||
auto actor_id = actor.get();
|
||||
actors.push_back(std::move(actor));
|
||||
|
||||
@ -127,20 +126,20 @@ TEST(Mtproto, GetHostByNameActor) {
|
||||
}
|
||||
|
||||
TEST(Time, to_unix_time) {
|
||||
ASSERT_EQ(0, HttpDate::to_unix_time(1970, 1, 1, 0, 0, 0).move_as_ok());
|
||||
ASSERT_EQ(60 * 60 + 60 + 1, HttpDate::to_unix_time(1970, 1, 1, 1, 1, 1).move_as_ok());
|
||||
ASSERT_EQ(24 * 60 * 60, HttpDate::to_unix_time(1970, 1, 2, 0, 0, 0).move_as_ok());
|
||||
ASSERT_EQ(31 * 24 * 60 * 60, HttpDate::to_unix_time(1970, 2, 1, 0, 0, 0).move_as_ok());
|
||||
ASSERT_EQ(365 * 24 * 60 * 60, HttpDate::to_unix_time(1971, 1, 1, 0, 0, 0).move_as_ok());
|
||||
ASSERT_EQ(1562780559, HttpDate::to_unix_time(2019, 7, 10, 17, 42, 39).move_as_ok());
|
||||
ASSERT_EQ(0, td::HttpDate::to_unix_time(1970, 1, 1, 0, 0, 0).move_as_ok());
|
||||
ASSERT_EQ(60 * 60 + 60 + 1, td::HttpDate::to_unix_time(1970, 1, 1, 1, 1, 1).move_as_ok());
|
||||
ASSERT_EQ(24 * 60 * 60, td::HttpDate::to_unix_time(1970, 1, 2, 0, 0, 0).move_as_ok());
|
||||
ASSERT_EQ(31 * 24 * 60 * 60, td::HttpDate::to_unix_time(1970, 2, 1, 0, 0, 0).move_as_ok());
|
||||
ASSERT_EQ(365 * 24 * 60 * 60, td::HttpDate::to_unix_time(1971, 1, 1, 0, 0, 0).move_as_ok());
|
||||
ASSERT_EQ(1562780559, td::HttpDate::to_unix_time(2019, 7, 10, 17, 42, 39).move_as_ok());
|
||||
}
|
||||
|
||||
TEST(Time, parse_http_date) {
|
||||
ASSERT_EQ(784887151, HttpDate::parse_http_date("Tue, 15 Nov 1994 08:12:31 GMT").move_as_ok());
|
||||
ASSERT_EQ(784887151, td::HttpDate::parse_http_date("Tue, 15 Nov 1994 08:12:31 GMT").move_as_ok());
|
||||
}
|
||||
|
||||
TEST(Mtproto, config) {
|
||||
ConcurrentScheduler sched;
|
||||
td::ConcurrentScheduler sched;
|
||||
int threads_n = 0;
|
||||
sched.init(threads_n);
|
||||
|
||||
@ -149,35 +148,37 @@ TEST(Mtproto, config) {
|
||||
auto guard = sched.get_main_guard();
|
||||
|
||||
auto run = [&](auto &func, bool is_test) {
|
||||
auto promise = PromiseCreator::lambda([&, num = cnt](Result<SimpleConfigResult> r_simple_config_result) {
|
||||
if (r_simple_config_result.is_ok()) {
|
||||
auto simple_config_result = r_simple_config_result.move_as_ok();
|
||||
auto date = simple_config_result.r_http_date.is_ok()
|
||||
? to_string(simple_config_result.r_http_date.ok())
|
||||
: (PSTRING() << simple_config_result.r_http_date.error());
|
||||
auto config = simple_config_result.r_config.is_ok() ? to_string(simple_config_result.r_config.ok())
|
||||
: (PSTRING() << simple_config_result.r_config.error());
|
||||
LOG(ERROR) << num << " " << date << " " << config;
|
||||
} else {
|
||||
LOG(ERROR) << num << " " << r_simple_config_result.error();
|
||||
}
|
||||
if (--cnt == 0) {
|
||||
Scheduler::instance()->finish();
|
||||
}
|
||||
});
|
||||
auto promise =
|
||||
td::PromiseCreator::lambda([&, num = cnt](td::Result<td::SimpleConfigResult> r_simple_config_result) {
|
||||
if (r_simple_config_result.is_ok()) {
|
||||
auto simple_config_result = r_simple_config_result.move_as_ok();
|
||||
auto date = simple_config_result.r_http_date.is_ok()
|
||||
? td::to_string(simple_config_result.r_http_date.ok())
|
||||
: (PSTRING() << simple_config_result.r_http_date.error());
|
||||
auto config = simple_config_result.r_config.is_ok()
|
||||
? to_string(simple_config_result.r_config.ok())
|
||||
: (PSTRING() << simple_config_result.r_config.error());
|
||||
LOG(ERROR) << num << " " << date << " " << config;
|
||||
} else {
|
||||
LOG(ERROR) << num << " " << r_simple_config_result.error();
|
||||
}
|
||||
if (--cnt == 0) {
|
||||
td::Scheduler::instance()->finish();
|
||||
}
|
||||
});
|
||||
cnt++;
|
||||
func(std::move(promise), nullptr, is_test, -1).release();
|
||||
};
|
||||
|
||||
run(get_simple_config_azure, false);
|
||||
run(get_simple_config_google_dns, false);
|
||||
run(get_simple_config_mozilla_dns, false);
|
||||
run(get_simple_config_azure, true);
|
||||
run(get_simple_config_google_dns, true);
|
||||
run(get_simple_config_mozilla_dns, true);
|
||||
run(get_simple_config_firebase_remote_config, false);
|
||||
run(get_simple_config_firebase_realtime, false);
|
||||
run(get_simple_config_firebase_firestore, false);
|
||||
run(td::get_simple_config_azure, false);
|
||||
run(td::get_simple_config_google_dns, false);
|
||||
run(td::get_simple_config_mozilla_dns, false);
|
||||
run(td::get_simple_config_azure, true);
|
||||
run(td::get_simple_config_google_dns, true);
|
||||
run(td::get_simple_config_mozilla_dns, true);
|
||||
run(td::get_simple_config_firebase_remote_config, false);
|
||||
run(td::get_simple_config_firebase_realtime, false);
|
||||
run(td::get_simple_config_firebase_firestore, false);
|
||||
}
|
||||
cnt--;
|
||||
if (cnt != 0) {
|
||||
@ -190,48 +191,49 @@ TEST(Mtproto, config) {
|
||||
}
|
||||
|
||||
TEST(Mtproto, encrypted_config) {
|
||||
string data =
|
||||
td::string data =
|
||||
" hO//tt \b\n\tiwPVovorKtIYtQ8y2ik7CqfJiJ4pJOCLRa4fBmNPixuRPXnBFF/3mTAAZoSyHq4SNylGHz0Cv1/"
|
||||
"FnWWdEV+BPJeOTk+ARHcNkuJBt0CqnfcVCoDOpKqGyq0U31s2MOpQvHgAG+Tlpg02syuH0E4dCGRw5CbJPARiynteb9y5fT5x/"
|
||||
"kmdp6BMR5tWQSQF0liH16zLh8BDSIdiMsikdcwnAvBwdNhRqQBqGx9MTh62MDmlebjtczE9Gz0z5cscUO2yhzGdphgIy6SP+"
|
||||
"bwaqLWYF0XdPGjKLMUEJW+rou6fbL1t/EUXPtU0XmQAnO0Fh86h+AqDMOe30N4qKrPQ== ";
|
||||
auto config = decode_config(data).move_as_ok();
|
||||
auto config = td::decode_config(data).move_as_ok();
|
||||
}
|
||||
|
||||
class TestPingActor final : public Actor {
|
||||
class TestPingActor final : public td::Actor {
|
||||
public:
|
||||
TestPingActor(IPAddress ip_address, Status *result) : ip_address_(ip_address), result_(result) {
|
||||
TestPingActor(td::IPAddress ip_address, td::Status *result) : ip_address_(ip_address), result_(result) {
|
||||
}
|
||||
|
||||
private:
|
||||
IPAddress ip_address_;
|
||||
unique_ptr<mtproto::PingConnection> ping_connection_;
|
||||
Status *result_;
|
||||
td::IPAddress ip_address_;
|
||||
td::unique_ptr<td::mtproto::PingConnection> ping_connection_;
|
||||
td::Status *result_;
|
||||
bool is_inited_ = false;
|
||||
|
||||
void start_up() final {
|
||||
auto r_socket = SocketFd::open(ip_address_);
|
||||
auto r_socket = td::SocketFd::open(ip_address_);
|
||||
if (r_socket.is_error()) {
|
||||
LOG(ERROR) << "Failed to open socket: " << r_socket.error();
|
||||
return stop();
|
||||
}
|
||||
|
||||
ping_connection_ = mtproto::PingConnection::create_req_pq(
|
||||
mtproto::RawConnection::create(ip_address_, BufferedFd<SocketFd>(r_socket.move_as_ok()),
|
||||
mtproto::TransportType{mtproto::TransportType::Tcp, 0, mtproto::ProxySecret()},
|
||||
nullptr),
|
||||
ping_connection_ = td::mtproto::PingConnection::create_req_pq(
|
||||
td::mtproto::RawConnection::create(
|
||||
ip_address_, td::BufferedFd<td::SocketFd>(r_socket.move_as_ok()),
|
||||
td::mtproto::TransportType{td::mtproto::TransportType::Tcp, 0, td::mtproto::ProxySecret()}, nullptr),
|
||||
3);
|
||||
|
||||
Scheduler::subscribe(ping_connection_->get_poll_info().extract_pollable_fd(this));
|
||||
td::Scheduler::subscribe(ping_connection_->get_poll_info().extract_pollable_fd(this));
|
||||
is_inited_ = true;
|
||||
set_timeout_in(10);
|
||||
yield();
|
||||
}
|
||||
|
||||
void tear_down() final {
|
||||
if (is_inited_) {
|
||||
Scheduler::unsubscribe_before_close(ping_connection_->get_poll_info().get_pollable_fd_ref());
|
||||
td::Scheduler::unsubscribe_before_close(ping_connection_->get_poll_info().get_pollable_fd_ref());
|
||||
}
|
||||
Scheduler::instance()->finish();
|
||||
td::Scheduler::instance()->finish();
|
||||
}
|
||||
|
||||
void loop() final {
|
||||
@ -247,13 +249,13 @@ class TestPingActor final : public Actor {
|
||||
}
|
||||
|
||||
void timeout_expired() final {
|
||||
*result_ = Status::Error("Timeout expired");
|
||||
*result_ = td::Status::Error("Timeout expired");
|
||||
stop();
|
||||
}
|
||||
};
|
||||
|
||||
static IPAddress get_default_ip_address() {
|
||||
IPAddress ip_address;
|
||||
static td::IPAddress get_default_ip_address() {
|
||||
td::IPAddress ip_address;
|
||||
#if TD_EMSCRIPTEN
|
||||
ip_address.init_host_port("venus.web.telegram.org/apiws", 443).ensure();
|
||||
#else
|
||||
@ -262,11 +264,11 @@ static IPAddress get_default_ip_address() {
|
||||
return ip_address;
|
||||
}
|
||||
|
||||
static int32 get_default_dc_id() {
|
||||
static td::int32 get_default_dc_id() {
|
||||
return 10002;
|
||||
}
|
||||
|
||||
class Mtproto_ping final : public Test {
|
||||
class Mtproto_ping final : public td::Test {
|
||||
public:
|
||||
using Test::Test;
|
||||
bool step() final {
|
||||
@ -290,60 +292,60 @@ class Mtproto_ping final : public Test {
|
||||
|
||||
private:
|
||||
bool is_inited_ = false;
|
||||
ConcurrentScheduler sched_;
|
||||
Status result_;
|
||||
td::ConcurrentScheduler sched_;
|
||||
td::Status result_;
|
||||
};
|
||||
RegisterTest<Mtproto_ping> mtproto_ping("Mtproto_ping");
|
||||
td::RegisterTest<Mtproto_ping> mtproto_ping("Mtproto_ping");
|
||||
|
||||
class HandshakeContext final : public mtproto::AuthKeyHandshakeContext {
|
||||
class HandshakeContext final : public td::mtproto::AuthKeyHandshakeContext {
|
||||
public:
|
||||
mtproto::DhCallback *get_dh_callback() final {
|
||||
td::mtproto::DhCallback *get_dh_callback() final {
|
||||
return nullptr;
|
||||
}
|
||||
mtproto::PublicRsaKeyInterface *get_public_rsa_key_interface() final {
|
||||
td::mtproto::PublicRsaKeyInterface *get_public_rsa_key_interface() final {
|
||||
return &public_rsa_key;
|
||||
}
|
||||
|
||||
private:
|
||||
PublicRsaKeyShared public_rsa_key{DcId::empty(), true};
|
||||
td::PublicRsaKeyShared public_rsa_key{td::DcId::empty(), true};
|
||||
};
|
||||
|
||||
class HandshakeTestActor final : public Actor {
|
||||
class HandshakeTestActor final : public td::Actor {
|
||||
public:
|
||||
HandshakeTestActor(int32 dc_id, Status *result) : dc_id_(dc_id), result_(result) {
|
||||
HandshakeTestActor(td::int32 dc_id, td::Status *result) : dc_id_(dc_id), result_(result) {
|
||||
}
|
||||
|
||||
private:
|
||||
int32 dc_id_ = 0;
|
||||
Status *result_;
|
||||
td::int32 dc_id_ = 0;
|
||||
td::Status *result_;
|
||||
bool wait_for_raw_connection_ = false;
|
||||
unique_ptr<mtproto::RawConnection> raw_connection_;
|
||||
td::unique_ptr<td::mtproto::RawConnection> raw_connection_;
|
||||
bool wait_for_handshake_ = false;
|
||||
unique_ptr<mtproto::AuthKeyHandshake> handshake_;
|
||||
Status status_;
|
||||
td::unique_ptr<td::mtproto::AuthKeyHandshake> handshake_;
|
||||
td::Status status_;
|
||||
bool wait_for_result_ = false;
|
||||
|
||||
void tear_down() final {
|
||||
if (raw_connection_) {
|
||||
raw_connection_->close();
|
||||
}
|
||||
finish(Status::Error("Interrupted"));
|
||||
finish(td::Status::Error("Interrupted"));
|
||||
}
|
||||
void loop() final {
|
||||
if (!wait_for_raw_connection_ && !raw_connection_) {
|
||||
auto ip_address = get_default_ip_address();
|
||||
auto r_socket = SocketFd::open(ip_address);
|
||||
auto r_socket = td::SocketFd::open(ip_address);
|
||||
if (r_socket.is_error()) {
|
||||
finish(Status::Error(PSTRING() << "Failed to open socket: " << r_socket.error()));
|
||||
finish(td::Status::Error(PSTRING() << "Failed to open socket: " << r_socket.error()));
|
||||
return stop();
|
||||
}
|
||||
|
||||
raw_connection_ = mtproto::RawConnection::create(
|
||||
ip_address, BufferedFd<SocketFd>(r_socket.move_as_ok()),
|
||||
mtproto::TransportType{mtproto::TransportType::Tcp, 0, mtproto::ProxySecret()}, nullptr);
|
||||
raw_connection_ = td::mtproto::RawConnection::create(
|
||||
ip_address, td::BufferedFd<td::SocketFd>(r_socket.move_as_ok()),
|
||||
td::mtproto::TransportType{td::mtproto::TransportType::Tcp, 0, td::mtproto::ProxySecret()}, nullptr);
|
||||
}
|
||||
if (!wait_for_handshake_ && !handshake_) {
|
||||
handshake_ = make_unique<mtproto::AuthKeyHandshake>(dc_id_, 3600);
|
||||
handshake_ = td::make_unique<td::mtproto::AuthKeyHandshake>(dc_id_, 3600);
|
||||
}
|
||||
if (raw_connection_ && handshake_) {
|
||||
if (wait_for_result_) {
|
||||
@ -353,34 +355,37 @@ class HandshakeTestActor final : public Actor {
|
||||
return stop();
|
||||
}
|
||||
if (!handshake_->is_ready_for_finish()) {
|
||||
finish(Status::Error("Key is not ready.."));
|
||||
finish(td::Status::Error("Key is not ready.."));
|
||||
return stop();
|
||||
}
|
||||
finish(Status::OK());
|
||||
finish(td::Status::OK());
|
||||
return stop();
|
||||
}
|
||||
|
||||
wait_for_result_ = true;
|
||||
create_actor<mtproto::HandshakeActor>(
|
||||
"HandshakeActor", std::move(handshake_), std::move(raw_connection_), make_unique<HandshakeContext>(), 10.0,
|
||||
PromiseCreator::lambda([self = actor_id(this)](Result<unique_ptr<mtproto::RawConnection>> raw_connection) {
|
||||
send_closure(self, &HandshakeTestActor::got_connection, std::move(raw_connection), 1);
|
||||
}),
|
||||
PromiseCreator::lambda([self = actor_id(this)](Result<unique_ptr<mtproto::AuthKeyHandshake>> handshake) {
|
||||
send_closure(self, &HandshakeTestActor::got_handshake, std::move(handshake), 1);
|
||||
}))
|
||||
td::create_actor<td::mtproto::HandshakeActor>(
|
||||
"HandshakeActor", std::move(handshake_), std::move(raw_connection_), td::make_unique<HandshakeContext>(),
|
||||
10.0,
|
||||
td::PromiseCreator::lambda(
|
||||
[self = actor_id(this)](td::Result<td::unique_ptr<td::mtproto::RawConnection>> raw_connection) {
|
||||
td::send_closure(self, &HandshakeTestActor::got_connection, std::move(raw_connection), 1);
|
||||
}),
|
||||
td::PromiseCreator::lambda(
|
||||
[self = actor_id(this)](td::Result<td::unique_ptr<td::mtproto::AuthKeyHandshake>> handshake) {
|
||||
td::send_closure(self, &HandshakeTestActor::got_handshake, std::move(handshake), 1);
|
||||
}))
|
||||
.release();
|
||||
wait_for_raw_connection_ = true;
|
||||
wait_for_handshake_ = true;
|
||||
}
|
||||
}
|
||||
|
||||
void got_connection(Result<unique_ptr<mtproto::RawConnection>> r_raw_connection, int32 dummy) {
|
||||
void got_connection(td::Result<td::unique_ptr<td::mtproto::RawConnection>> r_raw_connection, bool dummy) {
|
||||
CHECK(wait_for_raw_connection_);
|
||||
wait_for_raw_connection_ = false;
|
||||
if (r_raw_connection.is_ok()) {
|
||||
raw_connection_ = r_raw_connection.move_as_ok();
|
||||
status_ = Status::OK();
|
||||
status_ = td::Status::OK();
|
||||
} else {
|
||||
status_ = r_raw_connection.move_as_error();
|
||||
}
|
||||
@ -388,7 +393,7 @@ class HandshakeTestActor final : public Actor {
|
||||
loop();
|
||||
}
|
||||
|
||||
void got_handshake(Result<unique_ptr<mtproto::AuthKeyHandshake>> r_handshake, int32 dummy) {
|
||||
void got_handshake(td::Result<td::unique_ptr<td::mtproto::AuthKeyHandshake>> r_handshake, bool dummy) {
|
||||
CHECK(wait_for_handshake_);
|
||||
wait_for_handshake_ = false;
|
||||
CHECK(r_handshake.is_ok());
|
||||
@ -396,17 +401,17 @@ class HandshakeTestActor final : public Actor {
|
||||
loop();
|
||||
}
|
||||
|
||||
void finish(Status status) {
|
||||
void finish(td::Status status) {
|
||||
if (!result_) {
|
||||
return;
|
||||
}
|
||||
*result_ = std::move(status);
|
||||
result_ = nullptr;
|
||||
Scheduler::instance()->finish();
|
||||
td::Scheduler::instance()->finish();
|
||||
}
|
||||
};
|
||||
|
||||
class Mtproto_handshake final : public Test {
|
||||
class Mtproto_handshake final : public td::Test {
|
||||
public:
|
||||
using Test::Test;
|
||||
bool step() final {
|
||||
@ -430,55 +435,56 @@ class Mtproto_handshake final : public Test {
|
||||
|
||||
private:
|
||||
bool is_inited_ = false;
|
||||
ConcurrentScheduler sched_;
|
||||
Status result_;
|
||||
td::ConcurrentScheduler sched_;
|
||||
td::Status result_;
|
||||
};
|
||||
RegisterTest<Mtproto_handshake> mtproto_handshake("Mtproto_handshake");
|
||||
td::RegisterTest<Mtproto_handshake> mtproto_handshake("Mtproto_handshake");
|
||||
|
||||
class Socks5TestActor final : public Actor {
|
||||
class Socks5TestActor final : public td::Actor {
|
||||
public:
|
||||
void start_up() final {
|
||||
auto promise = PromiseCreator::lambda([actor_id = actor_id(this)](Result<BufferedFd<SocketFd>> res) {
|
||||
send_closure(actor_id, &Socks5TestActor::on_result, std::move(res), false);
|
||||
});
|
||||
auto promise =
|
||||
td::PromiseCreator::lambda([actor_id = actor_id(this)](td::Result<td::BufferedFd<td::SocketFd>> res) {
|
||||
td::send_closure(actor_id, &Socks5TestActor::on_result, std::move(res), false);
|
||||
});
|
||||
|
||||
class Callback final : public TransparentProxy::Callback {
|
||||
class Callback final : public td::TransparentProxy::Callback {
|
||||
public:
|
||||
explicit Callback(Promise<BufferedFd<SocketFd>> promise) : promise_(std::move(promise)) {
|
||||
explicit Callback(td::Promise<td::BufferedFd<td::SocketFd>> promise) : promise_(std::move(promise)) {
|
||||
}
|
||||
void set_result(Result<BufferedFd<SocketFd>> result) final {
|
||||
void set_result(td::Result<td::BufferedFd<td::SocketFd>> result) final {
|
||||
promise_.set_result(std::move(result));
|
||||
}
|
||||
void on_connected() final {
|
||||
}
|
||||
|
||||
private:
|
||||
Promise<BufferedFd<SocketFd>> promise_;
|
||||
td::Promise<td::BufferedFd<td::SocketFd>> promise_;
|
||||
};
|
||||
|
||||
IPAddress socks5_ip;
|
||||
td::IPAddress socks5_ip;
|
||||
socks5_ip.init_ipv4_port("131.191.89.104", 43077).ensure();
|
||||
IPAddress mtproto_ip_address = get_default_ip_address();
|
||||
td::IPAddress mtproto_ip_address = get_default_ip_address();
|
||||
|
||||
auto r_socket = SocketFd::open(socks5_ip);
|
||||
auto r_socket = td::SocketFd::open(socks5_ip);
|
||||
if (r_socket.is_error()) {
|
||||
return promise.set_error(Status::Error(PSTRING() << "Failed to open socket: " << r_socket.error()));
|
||||
return promise.set_error(td::Status::Error(PSTRING() << "Failed to open socket: " << r_socket.error()));
|
||||
}
|
||||
create_actor<Socks5>("socks5", r_socket.move_as_ok(), mtproto_ip_address, "", "",
|
||||
make_unique<Callback>(std::move(promise)), actor_shared(this))
|
||||
td::create_actor<td::Socks5>("socks5", r_socket.move_as_ok(), mtproto_ip_address, "", "",
|
||||
td::make_unique<Callback>(std::move(promise)), actor_shared(this))
|
||||
.release();
|
||||
}
|
||||
|
||||
private:
|
||||
void on_result(Result<BufferedFd<SocketFd>> res, bool dummy) {
|
||||
void on_result(td::Result<td::BufferedFd<td::SocketFd>> res, bool dummy) {
|
||||
res.ensure();
|
||||
Scheduler::instance()->finish();
|
||||
td::Scheduler::instance()->finish();
|
||||
}
|
||||
};
|
||||
|
||||
TEST(Mtproto, socks5) {
|
||||
return;
|
||||
ConcurrentScheduler sched;
|
||||
td::ConcurrentScheduler sched;
|
||||
int threads_n = 0;
|
||||
sched.init(threads_n);
|
||||
|
||||
@ -491,7 +497,7 @@ TEST(Mtproto, socks5) {
|
||||
}
|
||||
|
||||
TEST(Mtproto, notifications) {
|
||||
vector<string> pushes = {
|
||||
td::vector<td::string> pushes = {
|
||||
"eyJwIjoiSkRnQ3NMRWxEaWhyVWRRN1pYM3J1WVU4TlRBMFhMb0N6UWRNdzJ1cWlqMkdRbVR1WXVvYXhUeFJHaG1QQm8yVElYZFBzX2N3b2RIb3lY"
|
||||
"b2drVjM1dVl0UzdWeElNX1FNMDRKMG1mV3ZZWm4zbEtaVlJ0aFVBNGhYUWlaN0pfWDMyZDBLQUlEOWgzRnZwRjNXUFRHQWRaVkdFYzg3bnFPZ3hD"
|
||||
"NUNMRkM2SU9fZmVqcEpaV2RDRlhBWWpwc1k2aktrbVNRdFZ1MzE5ZW04UFVieXZudFpfdTNud2hjQ0czMk96TGp4S1kyS1lzU21JZm1GMzRmTmw1"
|
||||
@ -501,64 +507,67 @@ TEST(Mtproto, notifications) {
|
||||
"TkY1aXJRQlZ4UUFLQlRBekhPTGZIS3BhQXdoaWd5b3NQd0piWnJVV2xRWmh4eEozUFUzZjBNRTEwX0xNT0pFN0xsVUFaY2dabUNaX2V1QmNPZWNK"
|
||||
"VERxRkpIRGZjN2pBOWNrcFkyNmJRT2dPUEhCeHlEMUVrNVdQcFpLTnlBODVuYzQ1eHFPdERqcU5aVmFLU3pKb2VIcXBQMnJqR29kN2M5YkxsdGd5"
|
||||
"Q0NGd2NBU3dJeDc3QWNWVXY1UnVZIn0"};
|
||||
string key =
|
||||
td::string key =
|
||||
"uBa5yu01a-nJJeqsR3yeqMs6fJLYXjecYzFcvS6jIwS3nefBIr95LWrTm-IbRBNDLrkISz1Sv0KYpDzhU8WFRk1D0V_"
|
||||
"qyO7XsbDPyrYxRBpGxofJUINSjb1uCxoSdoh1_F0UXEA2fWWKKVxL0DKUQssZfbVj3AbRglsWpH-jDK1oc6eBydRiS3i4j-"
|
||||
"H0yJkEMoKRgaF9NaYI4u26oIQ-Ez46kTVU-R7e3acdofOJKm7HIKan_5ZMg82Dvec2M6vc_"
|
||||
"I54Vs28iBx8IbBO1y5z9WSScgW3JCvFFKP2MXIu7Jow5-cpUx6jXdzwRUb9RDApwAFKi45zpv8eb3uPCDAmIQ";
|
||||
vector<string> decrypted_payloads = {
|
||||
td::vector<td::string> decrypted_payloads = {
|
||||
"eyJsb2Nfa2V5IjoiTUVTU0FHRV9URVhUIiwibG9jX2FyZ3MiOlsiQXJzZW55IFNtaXJub3YiLCJhYmNkZWZnIl0sImN1c3RvbSI6eyJtc2dfaWQi"
|
||||
"OiI1OTAwNDciLCJmcm9tX2lkIjoiNjI4MTQifSwiYmFkZ2UiOiI0MDkifQ",
|
||||
"eyJsb2Nfa2V5IjoiIiwibG9jX2FyZ3MiOltdLCJjdXN0b20iOnsiY2hhbm5lbF9pZCI6IjExNzY4OTU0OTciLCJtYXhfaWQiOiIxMzU5In0sImJh"
|
||||
"ZGdlIjoiMCJ9"};
|
||||
key = base64url_decode(key).move_as_ok();
|
||||
key = td::base64url_decode(key).move_as_ok();
|
||||
|
||||
for (size_t i = 0; i < pushes.size(); i++) {
|
||||
auto push = base64url_decode(pushes[i]).move_as_ok();
|
||||
auto decrypted_payload = base64url_decode(decrypted_payloads[i]).move_as_ok();
|
||||
auto push = td::base64url_decode(pushes[i]).move_as_ok();
|
||||
auto decrypted_payload = td::base64url_decode(decrypted_payloads[i]).move_as_ok();
|
||||
|
||||
auto key_id = mtproto::DhHandshake::calc_key_id(key);
|
||||
ASSERT_EQ(key_id, NotificationManager::get_push_receiver_id(push).ok());
|
||||
ASSERT_EQ(decrypted_payload, NotificationManager::decrypt_push(key_id, key, push).ok());
|
||||
auto key_id = td::mtproto::DhHandshake::calc_key_id(key);
|
||||
ASSERT_EQ(key_id, td::NotificationManager::get_push_receiver_id(push).ok());
|
||||
ASSERT_EQ(decrypted_payload, td::NotificationManager::decrypt_push(key_id, key, push).ok());
|
||||
}
|
||||
}
|
||||
|
||||
class FastPingTestActor final : public Actor {
|
||||
class FastPingTestActor final : public td::Actor {
|
||||
public:
|
||||
explicit FastPingTestActor(Status *result) : result_(result) {
|
||||
explicit FastPingTestActor(td::Status *result) : result_(result) {
|
||||
}
|
||||
|
||||
private:
|
||||
Status *result_;
|
||||
unique_ptr<mtproto::RawConnection> connection_;
|
||||
unique_ptr<mtproto::AuthKeyHandshake> handshake_;
|
||||
ActorOwn<> fast_ping_;
|
||||
td::Status *result_;
|
||||
td::unique_ptr<td::mtproto::RawConnection> connection_;
|
||||
td::unique_ptr<td::mtproto::AuthKeyHandshake> handshake_;
|
||||
td::ActorOwn<> fast_ping_;
|
||||
int iteration_{0};
|
||||
|
||||
void start_up() final {
|
||||
// Run handshake to create key and salt
|
||||
auto ip_address = get_default_ip_address();
|
||||
auto r_socket = SocketFd::open(ip_address);
|
||||
auto r_socket = td::SocketFd::open(ip_address);
|
||||
if (r_socket.is_error()) {
|
||||
*result_ = Status::Error(PSTRING() << "Failed to open socket: " << r_socket.error());
|
||||
*result_ = td::Status::Error(PSTRING() << "Failed to open socket: " << r_socket.error());
|
||||
return stop();
|
||||
}
|
||||
|
||||
auto raw_connection = mtproto::RawConnection::create(
|
||||
ip_address, BufferedFd<SocketFd>(r_socket.move_as_ok()),
|
||||
mtproto::TransportType{mtproto::TransportType::Tcp, 0, mtproto::ProxySecret()}, nullptr);
|
||||
auto handshake = make_unique<mtproto::AuthKeyHandshake>(get_default_dc_id(), 60 * 100 /*temp*/);
|
||||
create_actor<mtproto::HandshakeActor>(
|
||||
"HandshakeActor", std::move(handshake), std::move(raw_connection), make_unique<HandshakeContext>(), 10.0,
|
||||
PromiseCreator::lambda([self = actor_id(this)](Result<unique_ptr<mtproto::RawConnection>> raw_connection) {
|
||||
send_closure(self, &FastPingTestActor::got_connection, std::move(raw_connection), 1);
|
||||
}),
|
||||
PromiseCreator::lambda([self = actor_id(this)](Result<unique_ptr<mtproto::AuthKeyHandshake>> handshake) {
|
||||
send_closure(self, &FastPingTestActor::got_handshake, std::move(handshake), 1);
|
||||
}))
|
||||
auto raw_connection = td::mtproto::RawConnection::create(
|
||||
ip_address, td::BufferedFd<td::SocketFd>(r_socket.move_as_ok()),
|
||||
td::mtproto::TransportType{td::mtproto::TransportType::Tcp, 0, td::mtproto::ProxySecret()}, nullptr);
|
||||
auto handshake = td::make_unique<td::mtproto::AuthKeyHandshake>(get_default_dc_id(), 60 * 100 /*temp*/);
|
||||
td::create_actor<td::mtproto::HandshakeActor>(
|
||||
"HandshakeActor", std::move(handshake), std::move(raw_connection), td::make_unique<HandshakeContext>(), 10.0,
|
||||
td::PromiseCreator::lambda(
|
||||
[self = actor_id(this)](td::Result<td::unique_ptr<td::mtproto::RawConnection>> raw_connection) {
|
||||
td::send_closure(self, &FastPingTestActor::got_connection, std::move(raw_connection), 1);
|
||||
}),
|
||||
td::PromiseCreator::lambda(
|
||||
[self = actor_id(this)](td::Result<td::unique_ptr<td::mtproto::AuthKeyHandshake>> handshake) {
|
||||
td::send_closure(self, &FastPingTestActor::got_handshake, std::move(handshake), 1);
|
||||
}))
|
||||
.release();
|
||||
}
|
||||
void got_connection(Result<unique_ptr<mtproto::RawConnection>> r_raw_connection, int32 dummy) {
|
||||
|
||||
void got_connection(td::Result<td::unique_ptr<td::mtproto::RawConnection>> r_raw_connection, bool dummy) {
|
||||
if (r_raw_connection.is_error()) {
|
||||
*result_ = r_raw_connection.move_as_error();
|
||||
LOG(INFO) << "Receive " << *result_ << " instead of a connection";
|
||||
@ -568,7 +577,7 @@ class FastPingTestActor final : public Actor {
|
||||
loop();
|
||||
}
|
||||
|
||||
void got_handshake(Result<unique_ptr<mtproto::AuthKeyHandshake>> r_handshake, int32 dummy) {
|
||||
void got_handshake(td::Result<td::unique_ptr<td::mtproto::AuthKeyHandshake>> r_handshake, bool dummy) {
|
||||
if (r_handshake.is_error()) {
|
||||
*result_ = r_handshake.move_as_error();
|
||||
LOG(INFO) << "Receive " << *result_ << " instead of a handshake";
|
||||
@ -578,7 +587,7 @@ class FastPingTestActor final : public Actor {
|
||||
loop();
|
||||
}
|
||||
|
||||
void got_raw_connection(Result<unique_ptr<mtproto::RawConnection>> r_connection) {
|
||||
void got_raw_connection(td::Result<td::unique_ptr<td::mtproto::RawConnection>> r_connection) {
|
||||
if (r_connection.is_error()) {
|
||||
*result_ = r_connection.move_as_error();
|
||||
LOG(INFO) << "Receive " << *result_ << " instead of a handshake";
|
||||
@ -596,36 +605,37 @@ class FastPingTestActor final : public Actor {
|
||||
if (iteration_ == 6) {
|
||||
return stop();
|
||||
}
|
||||
unique_ptr<mtproto::AuthData> auth_data;
|
||||
td::unique_ptr<td::mtproto::AuthData> auth_data;
|
||||
if (iteration_ % 2 == 0) {
|
||||
auth_data = make_unique<mtproto::AuthData>();
|
||||
auth_data = td::make_unique<td::mtproto::AuthData>();
|
||||
auth_data->set_tmp_auth_key(handshake_->get_auth_key());
|
||||
auth_data->set_server_time_difference(handshake_->get_server_time_diff());
|
||||
auth_data->set_server_salt(handshake_->get_server_salt(), Time::now());
|
||||
auth_data->set_future_salts({mtproto::ServerSalt{0u, 1e20, 1e30}}, Time::now());
|
||||
auth_data->set_server_salt(handshake_->get_server_salt(), td::Time::now());
|
||||
auth_data->set_future_salts({td::mtproto::ServerSalt{0u, 1e20, 1e30}}, td::Time::now());
|
||||
auth_data->set_use_pfs(true);
|
||||
uint64 session_id = 0;
|
||||
td::uint64 session_id = 0;
|
||||
do {
|
||||
Random::secure_bytes(reinterpret_cast<uint8 *>(&session_id), sizeof(session_id));
|
||||
td::Random::secure_bytes(reinterpret_cast<td::uint8 *>(&session_id), sizeof(session_id));
|
||||
} while (session_id == 0);
|
||||
auth_data->set_session_id(session_id);
|
||||
}
|
||||
iteration_++;
|
||||
fast_ping_ = create_ping_actor(
|
||||
td::Slice(), std::move(connection_), std::move(auth_data),
|
||||
PromiseCreator::lambda([self = actor_id(this)](Result<unique_ptr<mtproto::RawConnection>> r_raw_connection) {
|
||||
send_closure(self, &FastPingTestActor::got_raw_connection, std::move(r_raw_connection));
|
||||
}),
|
||||
ActorShared<>());
|
||||
td::PromiseCreator::lambda(
|
||||
[self = actor_id(this)](td::Result<td::unique_ptr<td::mtproto::RawConnection>> r_raw_connection) {
|
||||
td::send_closure(self, &FastPingTestActor::got_raw_connection, std::move(r_raw_connection));
|
||||
}),
|
||||
td::ActorShared<>());
|
||||
}
|
||||
}
|
||||
|
||||
void tear_down() final {
|
||||
Scheduler::instance()->finish();
|
||||
td::Scheduler::instance()->finish();
|
||||
}
|
||||
};
|
||||
|
||||
class Mtproto_FastPing final : public Test {
|
||||
class Mtproto_FastPing final : public td::Test {
|
||||
public:
|
||||
using Test::Test;
|
||||
bool step() final {
|
||||
@ -649,14 +659,14 @@ class Mtproto_FastPing final : public Test {
|
||||
|
||||
private:
|
||||
bool is_inited_ = false;
|
||||
ConcurrentScheduler sched_;
|
||||
Status result_;
|
||||
td::ConcurrentScheduler sched_;
|
||||
td::Status result_;
|
||||
};
|
||||
RegisterTest<Mtproto_FastPing> mtproto_fastping("Mtproto_FastPing");
|
||||
td::RegisterTest<Mtproto_FastPing> mtproto_fastping("Mtproto_FastPing");
|
||||
|
||||
TEST(Mtproto, Grease) {
|
||||
std::string s(10000, '0');
|
||||
mtproto::Grease::init(s);
|
||||
td::string s(10000, '0');
|
||||
td::mtproto::Grease::init(s);
|
||||
for (auto c : s) {
|
||||
CHECK((c & 0xF) == 0xA);
|
||||
}
|
||||
@ -666,47 +676,48 @@ TEST(Mtproto, Grease) {
|
||||
}
|
||||
|
||||
TEST(Mtproto, TlsTransport) {
|
||||
ConcurrentScheduler sched;
|
||||
td::ConcurrentScheduler sched;
|
||||
int threads_n = 1;
|
||||
sched.init(threads_n);
|
||||
{
|
||||
auto guard = sched.get_main_guard();
|
||||
class RunTest final : public Actor {
|
||||
class RunTest final : public td::Actor {
|
||||
void start_up() final {
|
||||
class Callback final : public TransparentProxy::Callback {
|
||||
class Callback final : public td::TransparentProxy::Callback {
|
||||
public:
|
||||
void set_result(Result<BufferedFd<SocketFd>> result) final {
|
||||
void set_result(td::Result<td::BufferedFd<td::SocketFd>> result) final {
|
||||
if (result.is_ok()) {
|
||||
LOG(ERROR) << "Unexpectedly succeeded to connect to MTProto proxy";
|
||||
} else if (result.error().message() != "Response hash mismatch") {
|
||||
LOG(ERROR) << "Receive unexpected result " << result.error();
|
||||
}
|
||||
Scheduler::instance()->finish();
|
||||
td::Scheduler::instance()->finish();
|
||||
}
|
||||
void on_connected() final {
|
||||
}
|
||||
};
|
||||
|
||||
const std::string domain = "www.google.com";
|
||||
IPAddress ip_address;
|
||||
const td::string domain = "www.google.com";
|
||||
td::IPAddress ip_address;
|
||||
auto resolve_status = ip_address.init_host_port(domain, 443);
|
||||
if (resolve_status.is_error()) {
|
||||
LOG(ERROR) << resolve_status;
|
||||
Scheduler::instance()->finish();
|
||||
td::Scheduler::instance()->finish();
|
||||
return;
|
||||
}
|
||||
auto r_socket = SocketFd::open(ip_address);
|
||||
auto r_socket = td::SocketFd::open(ip_address);
|
||||
if (r_socket.is_error()) {
|
||||
LOG(ERROR) << "Failed to open socket: " << r_socket.error();
|
||||
Scheduler::instance()->finish();
|
||||
td::Scheduler::instance()->finish();
|
||||
return;
|
||||
}
|
||||
create_actor<mtproto::TlsInit>("TlsInit", r_socket.move_as_ok(), domain, "0123456789secret",
|
||||
make_unique<Callback>(), ActorShared<>(), Clocks::system() - Time::now())
|
||||
td::create_actor<td::mtproto::TlsInit>("TlsInit", r_socket.move_as_ok(), domain, "0123456789secret",
|
||||
td::make_unique<Callback>(), td::ActorShared<>(),
|
||||
td::Clocks::system() - td::Time::now())
|
||||
.release();
|
||||
}
|
||||
};
|
||||
create_actor<RunTest>("RunTest").release();
|
||||
td::create_actor<RunTest>("RunTest").release();
|
||||
}
|
||||
|
||||
sched.start();
|
||||
|
Loading…
Reference in New Issue
Block a user