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:
parent
7754b3615e
commit
fcf59b4eb5
14 changed files with 489 additions and 12 deletions
|
@ -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_);
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue