1
0
Fork 0
mirror of https://github.com/ton-blockchain/ton synced 2025-03-09 15:40:10 +00:00

Reverse connections in adnl (#545)

Co-authored-by: SpyCheese <mikle98@yandex.ru>
This commit is contained in:
EmelyanenkoK 2022-12-06 17:06:54 +03:00 committed by GitHub
parent 7754b3615e
commit fcf59b4eb5
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
14 changed files with 489 additions and 12 deletions

View file

@ -185,7 +185,8 @@ td::Ref<AdnlAddressImpl> AdnlAddressImpl::create(const tl_object_ptr<ton_api::ad
*const_cast<ton_api::adnl_Address *>(addr.get()),
td::overloaded([&](const ton_api::adnl_address_udp &obj) { res = td::make_ref<AdnlAddressUdp>(obj); },
[&](const ton_api::adnl_address_udp6 &obj) { res = td::make_ref<AdnlAddressUdp6>(obj); },
[&](const ton_api::adnl_address_tunnel &obj) { res = td::make_ref<AdnlAddressTunnel>(obj); }));
[&](const ton_api::adnl_address_tunnel &obj) { res = td::make_ref<AdnlAddressTunnel>(obj); },
[&](const ton_api::adnl_address_reverse &obj) { res = td::make_ref<AdnlAddressReverse>(); }));
return res;
}
@ -202,7 +203,12 @@ AdnlAddressList::AdnlAddressList(const tl_object_ptr<ton_api::adnl_addressList>
version_ = static_cast<td::uint32>(addrs->version_);
std::vector<td::Ref<AdnlAddressImpl>> vec;
for (auto &addr : addrs->addrs_) {
vec.push_back(AdnlAddressImpl::create(addr));
auto obj = AdnlAddressImpl::create(addr);
if (obj->is_reverse()) {
has_reverse_ = true;
} else {
vec.push_back(std::move(obj));
}
}
addrs_ = std::move(vec);
reinit_date_ = addrs->reinit_date_;
@ -215,6 +221,9 @@ tl_object_ptr<ton_api::adnl_addressList> AdnlAddressList::tl() const {
for (auto &v : addrs_) {
addrs.emplace_back(v->tl());
}
if (has_reverse_) {
addrs.push_back(create_tl_object<ton_api::adnl_address_reverse>());
}
return create_tl_object<ton_api::adnl_addressList>(std::move(addrs), version_, reinit_date_, priority_, expire_at_);
}

View file

@ -39,6 +39,9 @@ class AdnlAddressImpl : public td::CntObject {
virtual td::actor::ActorOwn<AdnlNetworkConnection> create_connection(
td::actor::ActorId<AdnlNetworkManager> network_manager, td::actor::ActorId<Adnl> adnl,
std::unique_ptr<AdnlNetworkConnection::Callback> callback) const = 0;
virtual bool is_reverse() const {
return false;
}
static td::Ref<AdnlAddressImpl> create(const tl_object_ptr<ton_api::adnl_Address> &addr);
};
@ -54,6 +57,7 @@ class AdnlAddressList {
td::int32 priority_;
td::int32 expire_at_;
std::vector<AdnlAddress> addrs_;
bool has_reverse_{false};
public:
static constexpr td::uint32 max_serialized_size() {
@ -102,6 +106,13 @@ class AdnlAddressList {
static td::Result<AdnlAddressList> create(const tl_object_ptr<ton_api::adnl_addressList> &addr_list);
td::Status add_udp_address(td::IPAddress addr);
void set_reverse(bool x = true) {
has_reverse_ = x;
}
bool has_reverse() const {
return has_reverse_;
}
};
} // namespace adnl

View file

@ -116,6 +116,31 @@ class AdnlAddressTunnel : public AdnlAddressImpl {
std::unique_ptr<AdnlNetworkConnection::Callback> callback) const override;
};
class AdnlAddressReverse : public AdnlAddressImpl {
public:
AdnlAddressReverse *make_copy() const override {
return new AdnlAddressReverse();
}
bool is_public() const override {
return true;
}
td::uint32 serialized_size() const override {
return 4;
}
tl_object_ptr<ton_api::adnl_Address> tl() const override {
return create_tl_object<ton_api::adnl_address_reverse>();
}
td::actor::ActorOwn<AdnlNetworkConnection> create_connection(
td::actor::ActorId<AdnlNetworkManager> network_manager, td::actor::ActorId<Adnl> adnl,
std::unique_ptr<AdnlNetworkConnection::Callback> callback) const override {
LOG(ERROR) << "Cannot create connection for AdnlAddressReverse";
return {};
}
bool is_reverse() const override {
return true;
}
};
} // namespace adnl
} // namespace ton

View file

@ -121,7 +121,7 @@ void AdnlLocalId::update_address_list(AdnlAddressList addr_list) {
}
void AdnlLocalId::publish_address_list() {
if (dht_node_.empty() || addr_list_.empty() || addr_list_.size() == 0) {
if (dht_node_.empty() || addr_list_.empty() || (addr_list_.size() == 0 && !addr_list_.has_reverse())) {
VLOG(ADNL_NOTICE) << this << ": skipping public addr list, because localid (or dht node) not fully initialized";
return;
}
@ -175,6 +175,17 @@ void AdnlLocalId::publish_address_list() {
td::actor::send_closure(keyring_, &keyring::Keyring::sign_message, short_id_.pubkey_hash(), std::move(B),
std::move(P));
if (addr_list_.has_reverse()) {
td::actor::send_closure(
dht_node_, &dht::Dht::register_reverse_connection, id_, [print_id = print_id()](td::Result<td::Unit> R) {
if (R.is_error()) {
VLOG(ADNL_NOTICE) << print_id << ": failed to register reverse connection in DHT: " << R.move_as_error();
} else {
VLOG(ADNL_INFO) << print_id << ": registered reverse connection";
}
});
}
}
AdnlLocalId::AdnlLocalId(AdnlNodeIdFull id, AdnlAddressList addr_list, td::uint32 mode,

View file

@ -113,6 +113,7 @@ void AdnlPeerPairImpl::discover() {
}
void AdnlPeerPairImpl::receive_packet_checked(AdnlPacket packet) {
request_reverse_ping_after_ = td::Timestamp::in(15.0);
auto d = Adnl::adnl_start_time();
if (packet.dst_reinit_date() > d) {
VLOG(ADNL_WARNING) << this << ": dropping IN message: too new our reinit date " << packet.dst_reinit_date();
@ -653,10 +654,15 @@ td::Result<std::pair<td::actor::ActorId<AdnlNetworkConnection>, bool>> AdnlPeerP
}
if (conns_.size() == 0 && priority_conns_.size() == 0) {
return td::Status::Error(ErrorCode::notready, PSTRING()
<< "empty network information: version=" << addr_list_.version()
<< " reinit_date=" << addr_list_.reinit_date()
<< " real_reinit_date=" << reinit_date_);
if (has_reverse_addr_) {
request_reverse_ping();
return td::Status::Error(ErrorCode::notready, "waiting for reverse ping");
} else {
return td::Status::Error(ErrorCode::notready, PSTRING()
<< "empty network information: version=" << addr_list_.version()
<< " reinit_date=" << addr_list_.reinit_date()
<< " real_reinit_date=" << reinit_date_);
}
}
for (auto &conn : priority_conns_) {
@ -704,11 +710,18 @@ void AdnlPeerPairImpl::update_addr_list(AdnlAddressList addr_list) {
VLOG(ADNL_INFO) << this << ": updating addr list to version " << addr_list.version() << " size=" << addr_list.size();
const auto addrs = addr_list.addrs();
has_reverse_addr_ = addr_list.has_reverse();
if (has_reverse_addr_ && addrs.empty()) {
return;
}
std::vector<Conn> conns;
auto &old_conns = priority ? priority_conns_ : conns_;
size_t idx = 0;
for (const auto &addr : addrs) {
if (addr->is_reverse()) {
continue;
}
if ((mode_ & static_cast<td::uint32>(AdnlLocalIdMode::direct_only)) && !addr->is_public()) {
continue;
}
@ -730,7 +743,7 @@ void AdnlPeerPairImpl::get_conn_ip_str(td::Promise<td::string> promise) {
promise.set_value("undefined");
return;
}
for (auto &conn : priority_conns_) {
if (conn.ready()) {
td::actor::send_closure(conn.conn, &AdnlNetworkConnection::get_ip_str, std::move(promise));
@ -743,7 +756,7 @@ void AdnlPeerPairImpl::get_conn_ip_str(td::Promise<td::string> promise) {
return;
}
}
promise.set_value("undefined");
}
@ -868,7 +881,7 @@ void AdnlPeerImpl::get_conn_ip_str(AdnlNodeIdShort l_id, td::Promise<td::string>
if (it == peer_pairs_.end()) {
promise.set_value("undefined");
return;
}
}
td::actor::send_closure(it->second, &AdnlPeerPair::get_conn_ip_str, std::move(promise));
}
@ -944,6 +957,36 @@ void AdnlPeerPairImpl::update_peer_id(AdnlNodeIdFull id) {
CHECK(!peer_id_.empty());
}
void AdnlPeerPairImpl::request_reverse_ping() {
if (request_reverse_ping_active_ || !request_reverse_ping_after_.is_in_past()) {
return;
}
VLOG(ADNL_INFO) << this << ": requesting reverse ping";
request_reverse_ping_after_ = td::Timestamp::in(15.0);
request_reverse_ping_active_ = true;
td::actor::send_closure(
local_actor_, &AdnlLocalId::get_self_node,
[SelfId = actor_id(this), peer = peer_id_short_, dht = dht_node_](td::Result<AdnlNode> R) {
if (R.is_error()) {
td::actor::send_closure(SelfId, &AdnlPeerPairImpl::request_reverse_ping_result, R.move_as_error());
return;
}
td::actor::send_closure(
dht, &dht::Dht::request_reverse_ping, R.move_as_ok(), peer, [SelfId](td::Result<td::Unit> R) {
td::actor::send_closure(SelfId, &AdnlPeerPairImpl::request_reverse_ping_result, std::move(R));
});
});
}
void AdnlPeerPairImpl::request_reverse_ping_result(td::Result<td::Unit> R) {
request_reverse_ping_active_ = false;
if (R.is_ok()) {
VLOG(ADNL_INFO) << this << ": reverse ping requested";
} else {
VLOG(ADNL_INFO) << this << ": failed to request reverse ping: " << R.move_as_error();
}
}
} // namespace adnl
} // namespace ton

View file

@ -153,6 +153,9 @@ class AdnlPeerPairImpl : public AdnlPeerPair {
}
}
void request_reverse_ping();
void request_reverse_ping_result(td::Result<td::Unit> R);
struct Conn {
class ConnCallback : public AdnlNetworkConnection::Callback {
public:
@ -250,6 +253,10 @@ class AdnlPeerPairImpl : public AdnlPeerPair {
td::Timestamp next_dht_query_at_ = td::Timestamp::never();
td::Timestamp next_db_update_at_ = td::Timestamp::never();
td::Timestamp retry_send_at_ = td::Timestamp::never();
bool has_reverse_addr_ = false;
td::Timestamp request_reverse_ping_after_ = td::Timestamp::now();
bool request_reverse_ping_active_ = false;
};
class AdnlPeerImpl : public AdnlPeer {