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

updated vm

- updated func/fift
- additional checks in block validator
- docs
- tunnel prototype in ADNL
This commit is contained in:
ton 2020-03-11 14:19:31 +04:00
parent ba76f1404e
commit 54c7a4dcc3
50 changed files with 972 additions and 300 deletions

View file

@ -21,6 +21,7 @@
#include "auto/tl/ton_api.hpp"
#include "td/utils/overloaded.h"
#include "td/net/UdpServer.h"
#include "keys/encryptor.h"
namespace ton {
@ -50,6 +51,59 @@ class AdnlNetworkConnectionUdp : public AdnlNetworkConnection {
std::unique_ptr<AdnlNetworkConnection::Callback> callback_;
};
class AdnlNetworkConnectionTunnel : public AdnlNetworkConnection {
public:
void send(AdnlNodeIdShort src, AdnlNodeIdShort dst, td::uint32 priority, td::BufferSlice message) override {
if (!encryptor_) {
VLOG(ADNL_INFO) << "tunnel: message [" << src << "->" << dst << "to bad tunnel. dropping";
return;
}
auto dataR = encryptor_->encrypt(message.as_slice());
if (dataR.is_error()) {
VLOG(ADNL_INFO) << "tunnel: message [" << src << "->" << dst << ": failed to encrypt: " << dataR.move_as_error();
return;
}
auto data = dataR.move_as_ok();
td::BufferSlice enc_message{data.size() + 32};
auto S = enc_message.as_slice();
S.copy_from(pub_key_hash_.as_slice());
S.remove_prefix(32);
S.copy_from(data.as_slice());
td::actor::send_closure(adnl_, &Adnl::send_message_ex, src, adnl_id_, std::move(enc_message),
Adnl::SendFlags::direct_only);
}
bool is_alive() const override {
return ready_.load(std::memory_order_consume);
}
bool is_active() const override {
return ready_.load(std::memory_order_consume);
}
void start_up() override {
auto R = pub_key_.create_encryptor();
if (R.is_error()) {
VLOG(ADNL_INFO) << "tunnel: bad public key: " << R.move_as_error();
return;
}
encryptor_ = R.move_as_ok();
pub_key_hash_ = pub_key_.compute_short_id();
//ready_.store(true, std::memory_order_release);
}
AdnlNetworkConnectionTunnel(td::actor::ActorId<AdnlNetworkManager> network_manager, td::actor::ActorId<Adnl> adnl,
adnl::AdnlNodeIdShort adnl_id, PublicKey pubkey,
std::unique_ptr<AdnlNetworkConnection::Callback> callback);
private:
td::actor::ActorId<AdnlNetworkManager> network_manager_;
td::actor::ActorId<Adnl> adnl_;
AdnlNodeIdShort adnl_id_;
PublicKey pub_key_;
PublicKeyHash pub_key_hash_;
std::unique_ptr<Encryptor> encryptor_;
std::atomic<bool> ready_{false};
std::unique_ptr<AdnlNetworkConnection::Callback> callback_;
};
void AdnlNetworkConnectionUdp::send(AdnlNodeIdShort src, AdnlNodeIdShort dst, td::uint32 priority,
td::BufferSlice message) {
LOG_CHECK(message.size() <= AdnlNetworkManager::get_mtu()) << "dst=" << addr_ << " size=" << message.size();
@ -71,12 +125,23 @@ AdnlNetworkConnectionUdp::AdnlNetworkConnectionUdp(td::actor::ActorId<AdnlNetwor
addr_.init_host_port(td::IPAddress::ipv6_to_str(ip.as_slice()), port).ensure();
}
AdnlNetworkConnectionTunnel::AdnlNetworkConnectionTunnel(td::actor::ActorId<AdnlNetworkManager> network_manager,
td::actor::ActorId<Adnl> adnl, adnl::AdnlNodeIdShort adnl_id,
PublicKey pubkey,
std::unique_ptr<AdnlNetworkConnection::Callback> callback)
: network_manager_(std::move(network_manager))
, adnl_(std::move(adnl))
, adnl_id_(adnl_id)
, pub_key_(std::move(pubkey))
, callback_(std::move(callback)) {
}
AdnlAddressImpl::Hash AdnlAddressImpl::get_hash() const {
return get_tl_object_sha_bits256(tl());
}
td::actor::ActorOwn<AdnlNetworkConnection> AdnlAddressUdp::create_connection(
td::actor::ActorId<AdnlNetworkManager> network_manager,
td::actor::ActorId<AdnlNetworkManager> network_manager, td::actor::ActorId<Adnl> adnl,
std::unique_ptr<AdnlNetworkConnection::Callback> callback) const {
return td::actor::create_actor<AdnlNetworkConnectionUdp>("udpconn", network_manager, ip_, port_, std::move(callback));
}
@ -87,7 +152,7 @@ AdnlAddressUdp::AdnlAddressUdp(const ton_api::adnl_address_udp &obj) {
}
td::actor::ActorOwn<AdnlNetworkConnection> AdnlAddressUdp6::create_connection(
td::actor::ActorId<AdnlNetworkManager> network_manager,
td::actor::ActorId<AdnlNetworkManager> network_manager, td::actor::ActorId<Adnl> adnl,
std::unique_ptr<AdnlNetworkConnection::Callback> callback) const {
return td::actor::create_actor<AdnlNetworkConnectionUdp>("udpconn", network_manager, ip_, port_, std::move(callback));
}
@ -97,16 +162,24 @@ AdnlAddressUdp6::AdnlAddressUdp6(const ton_api::adnl_address_udp6 &obj) {
port_ = static_cast<td::uint16>(obj.port_);
}
td::actor::ActorOwn<AdnlNetworkConnection> AdnlAddressTunnel::create_connection(
td::actor::ActorId<AdnlNetworkManager> network_manager, td::actor::ActorId<Adnl> adnl,
std::unique_ptr<AdnlNetworkConnection::Callback> callback) const {
return td::actor::create_actor<AdnlNetworkConnectionTunnel>("tunnelconn", network_manager, adnl, adnl_id_, pub_key_,
std::move(callback));
}
AdnlAddressTunnel::AdnlAddressTunnel(const ton_api::adnl_address_tunnel &obj) {
adnl_id_ = AdnlNodeIdShort{obj.to_};
pub_key_ = ton::PublicKey{obj.pubkey_};
}
td::Ref<AdnlAddressImpl> AdnlAddressImpl::create(const tl_object_ptr<ton_api::adnl_Address> &addr) {
td::Ref<AdnlAddressImpl> res = td::Ref<AdnlAddressImpl>{};
ton_api::downcast_call(*const_cast<ton_api::adnl_Address *>(addr.get()),
td::overloaded(
[&](const ton_api::adnl_address_udp &obj) {
res = td::Ref<AdnlAddressUdp>{true, obj};
},
[&](const ton_api::adnl_address_udp6 &obj) {
res = td::Ref<AdnlAddressUdp6>{true, obj};
}));
ton_api::downcast_call(
*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); }));
return res;
}

View file

@ -25,6 +25,8 @@ namespace ton {
namespace adnl {
class Adnl;
class AdnlAddressImpl : public td::CntObject {
public:
using Hash = td::Bits256;
@ -35,7 +37,7 @@ class AdnlAddressImpl : public td::CntObject {
virtual td::uint32 serialized_size() const = 0;
virtual tl_object_ptr<ton_api::adnl_Address> tl() const = 0;
virtual td::actor::ActorOwn<AdnlNetworkConnection> create_connection(
td::actor::ActorId<AdnlNetworkManager> network_manager,
td::actor::ActorId<AdnlNetworkManager> network_manager, td::actor::ActorId<Adnl> adnl,
std::unique_ptr<AdnlNetworkConnection::Callback> callback) const = 0;
static td::Ref<AdnlAddressImpl> create(const tl_object_ptr<ton_api::adnl_Address> &addr);

View file

@ -51,7 +51,7 @@ class AdnlAddressUdp : public AdnlAddressImpl {
return create_tl_object<ton_api::adnl_address_udp>(ip_, port_);
}
td::actor::ActorOwn<AdnlNetworkConnection> create_connection(
td::actor::ActorId<AdnlNetworkManager> network_manager,
td::actor::ActorId<AdnlNetworkManager> network_manager, td::actor::ActorId<Adnl> adnl,
std::unique_ptr<AdnlNetworkConnection::Callback> callback) const override;
};
@ -81,7 +81,38 @@ class AdnlAddressUdp6 : public AdnlAddressImpl {
return create_tl_object<ton_api::adnl_address_udp6>(ip_, port_);
}
td::actor::ActorOwn<AdnlNetworkConnection> create_connection(
td::actor::ActorId<AdnlNetworkManager> network_manager,
td::actor::ActorId<AdnlNetworkManager> network_manager, td::actor::ActorId<Adnl> adnl,
std::unique_ptr<AdnlNetworkConnection::Callback> callback) const override;
};
class AdnlAddressTunnel : public AdnlAddressImpl {
private:
AdnlNodeIdShort adnl_id_;
PublicKey pub_key_;
public:
explicit AdnlAddressTunnel(const ton_api::adnl_address_tunnel &obj);
AdnlAddressTunnel(AdnlNodeIdShort adnl_id, PublicKey pub_key)
: adnl_id_(std::move(adnl_id)), pub_key_(std::move(pub_key)) {
}
AdnlAddressTunnel *make_copy() const override {
return new AdnlAddressTunnel{*this};
}
bool is_public() const override {
return false;
}
td::uint32 serialized_size() const override {
return 4 + 32 + pub_key_.serialized_size();
}
tl_object_ptr<ton_api::adnl_Address> tl() const override {
return create_tl_object<ton_api::adnl_address_tunnel>(adnl_id_.bits256_value(), pub_key_.tl());
}
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;
};

View file

@ -249,6 +249,40 @@ class AdnlMessage {
}
};
class OutboundAdnlMessage {
public:
template <class T>
OutboundAdnlMessage(T m, td::uint32 flags) : message_{std::move(m)}, flags_(flags) {
}
td::uint32 flags() const {
return flags_;
}
void set_flags(td::uint32 f) {
flags_ = f;
}
tl_object_ptr<ton_api::adnl_Message> tl() const {
return message_.tl();
}
td::uint32 size() const {
return message_.size();
}
template <class F>
void visit(F &&f) {
message_.visit(std::move(f));
}
template <class F>
void visit(F &&f) const {
message_.visit(std::move(f));
}
AdnlMessage release() {
return std::move(message_);
}
private:
AdnlMessage message_;
td::uint32 flags_;
};
class AdnlMessageList {
public:
AdnlMessageList() {
@ -291,6 +325,48 @@ class AdnlMessageList {
std::vector<AdnlMessage> messages_;
};
class OutboundAdnlMessageList {
public:
OutboundAdnlMessageList() {
}
OutboundAdnlMessageList(tl_object_ptr<ton_api::adnl_Message> message, td::uint32 flags) {
auto msg = OutboundAdnlMessage{std::move(message), flags};
messages_.emplace_back(std::move(msg));
}
OutboundAdnlMessageList(std::vector<tl_object_ptr<ton_api::adnl_Message>> messages, td::uint32 flags) {
for (auto &message : messages) {
messages_.push_back(OutboundAdnlMessage{std::move(message), flags});
}
}
void push_back(OutboundAdnlMessage message) {
messages_.push_back(std::move(message));
}
td::uint32 size() const {
return static_cast<td::uint32>(messages_.size());
}
tl_object_ptr<ton_api::adnl_Message> one_message() const {
CHECK(size() == 1);
return messages_[0].tl();
}
std::vector<tl_object_ptr<ton_api::adnl_Message>> mult_messages() const {
std::vector<tl_object_ptr<ton_api::adnl_Message>> vec;
for (auto &m : messages_) {
vec.emplace_back(m.tl());
}
return vec;
}
static std::vector<tl_object_ptr<ton_api::adnl_Message>> empty_vector() {
return std::vector<tl_object_ptr<ton_api::adnl_Message>>{};
}
auto &vector() {
return messages_;
}
private:
std::vector<OutboundAdnlMessage> messages_;
};
} // namespace adnl
} // namespace ton

View file

@ -138,7 +138,8 @@ void AdnlPeerTableImpl::add_static_nodes_from_config(AdnlNodesList nodes) {
}
}
void AdnlPeerTableImpl::send_message_in(AdnlNodeIdShort src, AdnlNodeIdShort dst, AdnlMessage message) {
void AdnlPeerTableImpl::send_message_in(AdnlNodeIdShort src, AdnlNodeIdShort dst, AdnlMessage message,
td::uint32 flags) {
auto it = peers_.find(dst);
if (it == peers_.end()) {
@ -152,7 +153,7 @@ void AdnlPeerTableImpl::send_message_in(AdnlNodeIdShort src, AdnlNodeIdShort dst
}
td::actor::send_closure(it->second, &AdnlPeer::send_one_message, src, it2->second.second, it2->second.first.get(),
std::move(message));
OutboundAdnlMessage{std::move(message), flags});
}
void AdnlPeerTableImpl::answer_query(AdnlNodeIdShort src, AdnlNodeIdShort dst, AdnlQueryId query_id,
@ -162,7 +163,7 @@ void AdnlPeerTableImpl::answer_query(AdnlNodeIdShort src, AdnlNodeIdShort dst, A
<< "]: message too big: size=" << data.size();
return;
}
send_message_in(src, dst, adnlmessage::AdnlMessageAnswer{query_id, std::move(data)});
send_message_in(src, dst, adnlmessage::AdnlMessageAnswer{query_id, std::move(data)}, 0);
}
void AdnlPeerTableImpl::send_query(AdnlNodeIdShort src, AdnlNodeIdShort dst, std::string name,
@ -185,7 +186,7 @@ void AdnlPeerTableImpl::send_query(AdnlNodeIdShort src, AdnlNodeIdShort dst, std
}
td::actor::send_closure(it->second, &AdnlPeer::send_query, src, it2->second.second, it2->second.first.get(), name,
std::move(promise), timeout, std::move(data));
std::move(promise), timeout, std::move(data), 0);
}
void AdnlPeerTableImpl::add_id_ex(AdnlNodeIdFull id, AdnlAddressList addr_list, td::uint32 mode) {

View file

@ -91,7 +91,7 @@ class AdnlPeerTable : public Adnl {
virtual void receive_packet(td::IPAddress addr, td::BufferSlice data) = 0;
virtual void receive_decrypted_packet(AdnlNodeIdShort dst, AdnlPacket packet) = 0;
virtual void send_message_in(AdnlNodeIdShort src, AdnlNodeIdShort dst, AdnlMessage message) = 0;
virtual void send_message_in(AdnlNodeIdShort src, AdnlNodeIdShort dst, AdnlMessage message, td::uint32 flags) = 0;
virtual void register_channel(AdnlChannelIdShort id, td::actor::ActorId<AdnlChannel> channel) = 0;
virtual void unregister_channel(AdnlChannelIdShort id) = 0;

View file

@ -45,14 +45,17 @@ class AdnlPeerTableImpl : public AdnlPeerTable {
void receive_packet(td::IPAddress addr, td::BufferSlice data) override;
void receive_decrypted_packet(AdnlNodeIdShort dst, AdnlPacket data) override;
void send_message_in(AdnlNodeIdShort src, AdnlNodeIdShort dst, AdnlMessage message) override;
void send_message_in(AdnlNodeIdShort src, AdnlNodeIdShort dst, AdnlMessage message, td::uint32 flags) override;
void send_message(AdnlNodeIdShort src, AdnlNodeIdShort dst, td::BufferSlice data) override {
send_message_ex(src, dst, std::move(data), 0);
}
void send_message_ex(AdnlNodeIdShort src, AdnlNodeIdShort dst, td::BufferSlice data, td::uint32 flags) override {
if (data.size() > huge_packet_max_size()) {
VLOG(ADNL_WARNING) << "dropping too big packet [" << src << "->" << dst << "]: size=" << data.size();
VLOG(ADNL_WARNING) << "DUMP: " << td::buffer_to_hex(data.as_slice().truncate(128));
return;
}
send_message_in(src, dst, AdnlMessage{adnlmessage::AdnlMessageCustom{std::move(data)}});
send_message_in(src, dst, AdnlMessage{adnlmessage::AdnlMessageCustom{std::move(data)}}, flags);
}
void answer_query(AdnlNodeIdShort src, AdnlNodeIdShort dst, AdnlQueryId query_id, td::BufferSlice data) override;
void send_query(AdnlNodeIdShort src, AdnlNodeIdShort dst, std::string name, td::Promise<td::BufferSlice> promise,

View file

@ -142,7 +142,7 @@ void AdnlPeerPairImpl::receive_packet_checked(AdnlPacket packet) {
update_addr_list(packet.priority_addr_list());
}
VLOG(ADNL_NOTICE) << this << ": dropping IN message old our reinit date " << packet.reinit_date() << " date=" << d;
auto M = AdnlMessage{adnlmessage::AdnlMessageNop{}};
auto M = OutboundAdnlMessage{adnlmessage::AdnlMessageNop{}, 0};
send_message(std::move(M));
return;
}
@ -231,113 +231,131 @@ void AdnlPeerPairImpl::deliver_message(AdnlMessage message) {
message.visit([&](const auto &obj) { this->process_message(obj); });
}
void AdnlPeerPairImpl::send_messages_in(std::vector<AdnlMessage> messages, bool allow_postpone) {
auto connR = get_conn();
if (connR.is_error()) {
if (!allow_postpone) {
VLOG(ADNL_NOTICE) << this << ": dropping OUT messages: cannot get conn: " << connR.move_as_error();
void AdnlPeerPairImpl::send_messages_in(std::vector<OutboundAdnlMessage> messages, bool allow_postpone) {
for (td::int32 idx = 0; idx < 2; idx++) {
std::vector<OutboundAdnlMessage> not_sent;
auto connR = get_conn(idx == 1);
if (connR.is_error()) {
if (!allow_postpone) {
VLOG(ADNL_NOTICE) << this << ": dropping OUT messages: cannot get conn: " << connR.move_as_error();
return;
}
VLOG(ADNL_INFO) << this << ": delaying OUT messages: cannot get conn: " << connR.move_as_error();
if (!retry_send_at_) {
retry_send_at_.relax(td::Timestamp::in(10.0));
alarm_timestamp().relax(retry_send_at_);
}
for (auto &m : messages) {
pending_messages_.push_back(std::move(m));
}
return;
}
VLOG(ADNL_INFO) << this << ": delaying OUT messages: cannot get conn: " << connR.move_as_error();
if (!retry_send_at_) {
retry_send_at_.relax(td::Timestamp::in(10.0));
alarm_timestamp().relax(retry_send_at_);
auto C = connR.move_as_ok();
bool is_direct = C.second;
auto conn = std::move(C.first);
if (idx == 1) {
CHECK(is_direct);
}
for (auto &m : messages) {
pending_messages_.push_back(std::move(m));
size_t ptr = 0;
bool first = true;
do {
size_t s = (channel_ready_ ? channel_packet_header_max_size() : packet_header_max_size());
if (first) {
s += 2 * addr_list_max_size();
}
AdnlPacket packet;
packet.set_seqno(++out_seqno_);
packet.set_confirm_seqno(in_seqno_);
if (first) {
if (!channel_inited_) {
auto M = adnlmessage::AdnlMessageCreateChannel{channel_pub_, channel_pk_date_};
s += M.size();
packet.add_message(std::move(M));
} else if (!channel_ready_) {
auto M = adnlmessage::AdnlMessageConfirmChannel{channel_pub_, peer_channel_pub_, channel_pk_date_};
s += M.size();
packet.add_message(std::move(M));
}
}
if (!addr_list_.empty()) {
packet.set_received_addr_list_version(addr_list_.version());
}
if (!priority_addr_list_.empty()) {
packet.set_received_priority_addr_list_version(priority_addr_list_.version());
}
while (ptr < messages.size()) {
auto &M = messages[ptr];
if (!is_direct && (M.flags() & Adnl::SendFlags::direct_only)) {
not_sent.push_back(std::move(M));
continue;
}
CHECK(M.size() <= get_mtu());
if (s + M.size() <= AdnlNetworkManager::get_mtu()) {
s += M.size();
packet.add_message(M.release());
ptr++;
} else {
break;
}
}
if (!channel_ready_) {
packet.set_reinit_date(Adnl::adnl_start_time(), reinit_date_);
packet.set_source(local_id_);
}
if (!first) {
if (!channel_inited_) {
auto M = adnlmessage::AdnlMessageCreateChannel{channel_pub_, channel_pk_date_};
if (s + M.size() <= AdnlNetworkManager::get_mtu()) {
s += M.size();
packet.add_message(std::move(M));
}
} else if (!channel_ready_) {
auto M = adnlmessage::AdnlMessageConfirmChannel{channel_pub_, peer_channel_pub_, channel_pk_date_};
if (s + M.size() <= AdnlNetworkManager::get_mtu()) {
s += M.size();
packet.add_message(std::move(M));
}
}
}
packet.run_basic_checks().ensure();
auto P = td::PromiseCreator::lambda([SelfId = actor_id(this), conn, id = print_id(),
via_channel = channel_ready_](td::Result<AdnlPacket> res) {
if (res.is_error()) {
LOG(ERROR) << id << ": dropping OUT message: error while creating packet: " << res.move_as_error();
} else {
td::actor::send_closure(SelfId, &AdnlPeerPairImpl::send_packet_continue, res.move_as_ok(), conn, via_channel);
}
});
td::actor::send_closure(local_actor_, &AdnlLocalId::update_packet, std::move(packet),
!channel_ready_ && ack_seqno_ == 0 && in_seqno_ == 0, !channel_ready_,
(first || s + addr_list_max_size() <= AdnlNetworkManager::get_mtu())
? peer_recv_addr_list_version_
: 0x7fffffff,
(first || s + 2 * addr_list_max_size() <= AdnlNetworkManager::get_mtu())
? peer_recv_priority_addr_list_version_
: 0x7fffffff,
std::move(P));
first = false;
} while (ptr < messages.size());
messages = std::move(not_sent);
if (!messages.size()) {
break;
}
return;
}
auto conn = connR.move_as_ok();
size_t ptr = 0;
bool first = true;
do {
size_t s = (channel_ready_ ? channel_packet_header_max_size() : packet_header_max_size());
if (first) {
s += 2 * addr_list_max_size();
}
AdnlPacket packet;
packet.set_seqno(++out_seqno_);
packet.set_confirm_seqno(in_seqno_);
if (first) {
if (!channel_inited_) {
auto M = adnlmessage::AdnlMessageCreateChannel{channel_pub_, channel_pk_date_};
s += M.size();
packet.add_message(std::move(M));
} else if (!channel_ready_) {
auto M = adnlmessage::AdnlMessageConfirmChannel{channel_pub_, peer_channel_pub_, channel_pk_date_};
s += M.size();
packet.add_message(std::move(M));
}
}
if (!addr_list_.empty()) {
packet.set_received_addr_list_version(addr_list_.version());
}
if (!priority_addr_list_.empty()) {
packet.set_received_priority_addr_list_version(priority_addr_list_.version());
}
while (ptr < messages.size()) {
auto &M = messages[ptr];
CHECK(M.size() <= get_mtu());
if (s + M.size() <= AdnlNetworkManager::get_mtu()) {
s += M.size();
packet.add_message(std::move(M));
ptr++;
} else {
break;
}
}
if (!channel_ready_) {
packet.set_reinit_date(Adnl::adnl_start_time(), reinit_date_);
packet.set_source(local_id_);
}
if (!first) {
if (!channel_inited_) {
auto M = adnlmessage::AdnlMessageCreateChannel{channel_pub_, channel_pk_date_};
if (s + M.size() <= AdnlNetworkManager::get_mtu()) {
s += M.size();
packet.add_message(std::move(M));
}
} else if (!channel_ready_) {
auto M = adnlmessage::AdnlMessageConfirmChannel{channel_pub_, peer_channel_pub_, channel_pk_date_};
if (s + M.size() <= AdnlNetworkManager::get_mtu()) {
s += M.size();
packet.add_message(std::move(M));
}
}
}
packet.run_basic_checks().ensure();
auto P = td::PromiseCreator::lambda([SelfId = actor_id(this), conn, id = print_id(),
via_channel = channel_ready_](td::Result<AdnlPacket> res) {
if (res.is_error()) {
LOG(ERROR) << id << ": dropping OUT message: error while creating packet: " << res.move_as_error();
} else {
td::actor::send_closure(SelfId, &AdnlPeerPairImpl::send_packet_continue, res.move_as_ok(), conn, via_channel);
}
});
td::actor::send_closure(
local_actor_, &AdnlLocalId::update_packet, std::move(packet),
!channel_ready_ && ack_seqno_ == 0 && in_seqno_ == 0, !channel_ready_,
(first || s + addr_list_max_size() <= AdnlNetworkManager::get_mtu()) ? peer_recv_addr_list_version_
: 0x7fffffff,
(first || s + 2 * addr_list_max_size() <= AdnlNetworkManager::get_mtu()) ? peer_recv_priority_addr_list_version_
: 0x7fffffff,
std::move(P));
first = false;
} while (ptr < messages.size());
}
void AdnlPeerPairImpl::send_messages(std::vector<AdnlMessage> messages) {
std::vector<AdnlMessage> new_vec;
void AdnlPeerPairImpl::send_messages(std::vector<OutboundAdnlMessage> messages) {
std::vector<OutboundAdnlMessage> new_vec;
for (auto &M : messages) {
if (M.size() <= get_mtu()) {
new_vec.push_back(std::move(M));
@ -357,7 +375,8 @@ void AdnlPeerPairImpl::send_messages(std::vector<AdnlMessage> messages) {
}
B.confirm_read(data.size());
new_vec.push_back(AdnlMessage{adnlmessage::AdnlMessagePart{hash, size, offset, std::move(data)}});
new_vec.push_back(
OutboundAdnlMessage{adnlmessage::AdnlMessagePart{hash, size, offset, std::move(data)}, M.flags()});
offset += part_size;
}
}
@ -402,7 +421,7 @@ void AdnlPeerPairImpl::send_packet_continue(AdnlPacket packet, td::actor::ActorI
}
void AdnlPeerPairImpl::send_query(std::string name, td::Promise<td::BufferSlice> promise, td::Timestamp timeout,
td::BufferSlice data) {
td::BufferSlice data, td::uint32 flags) {
AdnlQueryId id = AdnlQuery::random_query_id();
CHECK(out_queries_.count(id) == 0);
@ -412,7 +431,7 @@ void AdnlPeerPairImpl::send_query(std::string name, td::Promise<td::BufferSlice>
out_queries_[id] = AdnlQuery::create(std::move(promise), std::move(P), name, timeout, id);
send_message(adnlmessage::AdnlMessageQuery{id, std::move(data)});
send_message(OutboundAdnlMessage{adnlmessage::AdnlMessageQuery{id, std::move(data)}, flags});
}
void AdnlPeerPairImpl::alarm_query(AdnlQueryId id) {
@ -499,20 +518,20 @@ void AdnlPeerPairImpl::process_message(const adnlmessage::AdnlMessageReinit &mes
}
void AdnlPeerPairImpl::process_message(const adnlmessage::AdnlMessageQuery &message) {
auto P = td::PromiseCreator::lambda(
[SelfId = actor_id(this), query_id = message.query_id()](td::Result<td::BufferSlice> R) {
if (R.is_error()) {
LOG(WARNING) << "failed to answer query: " << R.move_as_error();
} else {
auto data = R.move_as_ok();
if (data.size() > Adnl::huge_packet_max_size()) {
LOG(WARNING) << "dropping too big answer query: size=" << data.size();
} else {
td::actor::send_closure(SelfId, &AdnlPeerPairImpl::send_message,
AdnlMessage{adnlmessage::AdnlMessageAnswer{query_id, std::move(data)}});
}
}
});
auto P = td::PromiseCreator::lambda([SelfId = actor_id(this), query_id = message.query_id(),
flags = static_cast<td::uint32>(0)](td::Result<td::BufferSlice> R) {
if (R.is_error()) {
LOG(WARNING) << "failed to answer query: " << R.move_as_error();
} else {
auto data = R.move_as_ok();
if (data.size() > Adnl::huge_packet_max_size()) {
LOG(WARNING) << "dropping too big answer query: size=" << data.size();
} else {
td::actor::send_closure(SelfId, &AdnlPeerPairImpl::send_message,
OutboundAdnlMessage{adnlmessage::AdnlMessageAnswer{query_id, std::move(data)}, flags});
}
}
});
td::actor::send_closure(local_actor_, &AdnlLocalId::deliver_query, peer_id_short_, message.data(), std::move(P));
}
@ -625,7 +644,7 @@ void AdnlPeerPairImpl::reinit(td::int32 date) {
}
}
td::Result<td::actor::ActorId<AdnlNetworkConnection>> AdnlPeerPairImpl::get_conn() {
td::Result<std::pair<td::actor::ActorId<AdnlNetworkConnection>, bool>> AdnlPeerPairImpl::get_conn(bool direct_only) {
if (!priority_addr_list_.empty() && priority_addr_list_.expire_at() < td::Clocks::system()) {
priority_addr_list_ = AdnlAddressList{};
priority_conns_.clear();
@ -639,13 +658,13 @@ td::Result<td::actor::ActorId<AdnlNetworkConnection>> AdnlPeerPairImpl::get_conn
}
for (auto &conn : priority_conns_) {
if (conn.ready()) {
return conn.conn.get();
if (conn.ready() && (!direct_only || conn.is_direct())) {
return std::make_pair(conn.conn.get(), conn.is_direct());
}
}
for (auto &conn : conns_) {
if (conn.ready()) {
return conn.conn.get();
if (conn.ready() && (!direct_only || conn.is_direct())) {
return std::make_pair(conn.conn.get(), conn.is_direct());
}
}
return td::Status::Error(ErrorCode::notready, "no active connections");
@ -695,7 +714,7 @@ void AdnlPeerPairImpl::update_addr_list(AdnlAddressList addr_list) {
if (idx < old_conns.size() && old_conns[idx].addr->get_hash() == hash) {
conns.push_back(std::move(old_conns[idx]));
} else {
conns.push_back(Conn{addr, actor_id(this), network_manager_});
conns.push_back(Conn{addr, actor_id(this), network_manager_, peer_table_});
}
idx++;
}
@ -718,10 +737,11 @@ void AdnlPeerImpl::update_id(AdnlNodeIdFull id) {
}
void AdnlPeerPairImpl::Conn::create_conn(td::actor::ActorId<AdnlPeerPairImpl> peer,
td::actor::ActorId<AdnlNetworkManager> network_manager) {
td::actor::ActorId<AdnlNetworkManager> network_manager,
td::actor::ActorId<Adnl> adnl) {
auto id = addr->get_hash();
conn = addr->create_connection(network_manager, std::make_unique<ConnCallback>(peer, id));
conn = addr->create_connection(network_manager, adnl, std::make_unique<ConnCallback>(peer, id));
}
void AdnlPeerPairImpl::conn_change_state(AdnlConnectionIdShort id, bool ready) {
@ -771,7 +791,7 @@ void AdnlPeerImpl::receive_packet(AdnlNodeIdShort dst, td::uint32 dst_mode, td::
}
void AdnlPeerImpl::send_messages(AdnlNodeIdShort src, td::uint32 src_mode, td::actor::ActorId<AdnlLocalId> src_actor,
std::vector<AdnlMessage> messages) {
std::vector<OutboundAdnlMessage> messages) {
auto it = peer_pairs_.find(src);
if (it == peer_pairs_.end()) {
auto X = AdnlPeerPair::create(network_manager_, peer_table_, src_mode, src_actor, actor_id(this), dht_node_, src,
@ -790,7 +810,7 @@ void AdnlPeerImpl::send_messages(AdnlNodeIdShort src, td::uint32 src_mode, td::a
void AdnlPeerImpl::send_query(AdnlNodeIdShort src, td::uint32 src_mode, td::actor::ActorId<AdnlLocalId> src_actor,
std::string name, td::Promise<td::BufferSlice> promise, td::Timestamp timeout,
td::BufferSlice data) {
td::BufferSlice data, td::uint32 flags) {
auto it = peer_pairs_.find(src);
if (it == peer_pairs_.end()) {
auto X = AdnlPeerPair::create(network_manager_, peer_table_, src_mode, src_actor, actor_id(this), dht_node_, src,
@ -804,7 +824,8 @@ void AdnlPeerImpl::send_query(AdnlNodeIdShort src, td::uint32 src_mode, td::acto
}
}
td::actor::send_closure(it->second, &AdnlPeerPair::send_query, name, std::move(promise), timeout, std::move(data));
td::actor::send_closure(it->second, &AdnlPeerPair::send_query, name, std::move(promise), timeout, std::move(data),
flags);
}
void AdnlPeerImpl::del_local_id(AdnlNodeIdShort local_id) {

View file

@ -43,9 +43,9 @@ class AdnlPeerPair : public td::actor::Actor {
virtual void receive_packet_checked(AdnlPacket packet) = 0;
virtual void receive_packet(AdnlPacket packet) = 0;
virtual void send_messages(std::vector<AdnlMessage> message) = 0;
inline void send_message(AdnlMessage message) {
std::vector<AdnlMessage> vec;
virtual void send_messages(std::vector<OutboundAdnlMessage> message) = 0;
inline void send_message(OutboundAdnlMessage message) {
std::vector<OutboundAdnlMessage> vec;
vec.push_back(std::move(message));
send_messages(std::move(vec));
}
@ -53,7 +53,7 @@ class AdnlPeerPair : public td::actor::Actor {
return Adnl::get_mtu() + 128;
}
virtual void send_query(std::string name, td::Promise<td::BufferSlice> promise, td::Timestamp timeout,
td::BufferSlice data) = 0;
td::BufferSlice data, td::uint32 flags) = 0;
virtual void alarm_query(AdnlQueryId query_id) = 0;
virtual void update_dht_node(td::actor::ActorId<dht::Dht> dht_node) = 0;
virtual void update_peer_id(AdnlNodeIdFull id) = 0;
@ -72,20 +72,20 @@ class AdnlPeer : public td::actor::Actor {
virtual void receive_packet(AdnlNodeIdShort dst, td::uint32 dst_mode, td::actor::ActorId<AdnlLocalId> dst_actor,
AdnlPacket message) = 0;
virtual void send_messages(AdnlNodeIdShort src, td::uint32 src_mode, td::actor::ActorId<AdnlLocalId> src_actor,
std::vector<AdnlMessage> messages) = 0;
std::vector<OutboundAdnlMessage> messages) = 0;
virtual void send_query(AdnlNodeIdShort src, td::uint32 src_mode, td::actor::ActorId<AdnlLocalId> src_actor,
std::string name, td::Promise<td::BufferSlice> promise, td::Timestamp timeout,
td::BufferSlice data) = 0;
td::BufferSlice data, td::uint32 flags) = 0;
void send_one_message(AdnlNodeIdShort src, td::uint32 src_mode, td::actor::ActorId<AdnlLocalId> src_actor,
AdnlMessage message) {
std::vector<AdnlMessage> vec;
OutboundAdnlMessage message) {
std::vector<OutboundAdnlMessage> vec;
vec.push_back(std::move(message));
send_messages(src, src_mode, src_actor, std::move(vec));
}
void send_message(AdnlNodeIdShort src, td::uint32 src_mode, td::actor::ActorId<AdnlLocalId> src_actor,
td::BufferSlice data) {
auto M = AdnlMessage{adnlmessage::AdnlMessageCustom{std::move(data)}};
td::BufferSlice data, td::uint32 flags) {
auto M = OutboundAdnlMessage{adnlmessage::AdnlMessageCustom{std::move(data)}, flags};
send_one_message(src, src_mode, src_actor, std::move(M));
}

View file

@ -71,11 +71,11 @@ class AdnlPeerPairImpl : public AdnlPeerPair {
void receive_packet(AdnlPacket packet) override;
void deliver_message(AdnlMessage message);
void send_messages_in(std::vector<AdnlMessage> messages, bool allow_postpone);
void send_messages(std::vector<AdnlMessage> messages) override;
void send_messages_in(std::vector<OutboundAdnlMessage> messages, bool allow_postpone);
void send_messages(std::vector<OutboundAdnlMessage> messages) override;
void send_packet_continue(AdnlPacket packet, td::actor::ActorId<AdnlNetworkConnection> conn, bool via_channel);
void send_query(std::string name, td::Promise<td::BufferSlice> promise, td::Timestamp timeout,
td::BufferSlice data) override;
void send_query(std::string name, td::Promise<td::BufferSlice> promise, td::Timestamp timeout, td::BufferSlice data,
td::uint32 flags) override;
void alarm_query(AdnlQueryId id) override;
@ -121,7 +121,7 @@ class AdnlPeerPairImpl : public AdnlPeerPair {
private:
void reinit(td::int32 date);
td::Result<td::actor::ActorId<AdnlNetworkConnection>> get_conn();
td::Result<std::pair<td::actor::ActorId<AdnlNetworkConnection>, bool>> get_conn(bool direct_only);
void create_channel(pubkeys::Ed25519 pub, td::uint32 date);
bool received_packet(td::uint64 seqno) const {
@ -170,9 +170,9 @@ class AdnlPeerPairImpl : public AdnlPeerPair {
td::actor::ActorOwn<AdnlNetworkConnection> conn;
Conn(AdnlAddress addr, td::actor::ActorId<AdnlPeerPairImpl> peer,
td::actor::ActorId<AdnlNetworkManager> network_manager)
td::actor::ActorId<AdnlNetworkManager> network_manager, td::actor::ActorId<Adnl> adnl)
: addr(std::move(addr)) {
create_conn(peer, network_manager);
create_conn(peer, network_manager, adnl);
}
Conn() {
}
@ -181,10 +181,15 @@ class AdnlPeerPairImpl : public AdnlPeerPair {
return !conn.empty() && conn.get_actor_unsafe().is_active();
}
void create_conn(td::actor::ActorId<AdnlPeerPairImpl> peer, td::actor::ActorId<AdnlNetworkManager> network_manager);
bool is_direct() {
return addr->is_public();
}
void create_conn(td::actor::ActorId<AdnlPeerPairImpl> peer, td::actor::ActorId<AdnlNetworkManager> network_manager,
td::actor::ActorId<Adnl> adnl);
};
std::vector<AdnlMessage> pending_messages_;
std::vector<OutboundAdnlMessage> pending_messages_;
td::actor::ActorId<AdnlNetworkManager> network_manager_;
td::actor::ActorId<AdnlPeerTable> peer_table_;
@ -250,9 +255,10 @@ class AdnlPeerImpl : public AdnlPeer {
void receive_packet(AdnlNodeIdShort dst, td::uint32 dst_mode, td::actor::ActorId<AdnlLocalId> dst_actor,
AdnlPacket packet) override;
void send_messages(AdnlNodeIdShort src, td::uint32 src_mode, td::actor::ActorId<AdnlLocalId> src_actor,
std::vector<AdnlMessage> messages) override;
std::vector<OutboundAdnlMessage> messages) override;
void send_query(AdnlNodeIdShort src, td::uint32 src_mode, td::actor::ActorId<AdnlLocalId> src_actor, std::string name,
td::Promise<td::BufferSlice> promise, td::Timestamp timeout, td::BufferSlice data) override;
td::Promise<td::BufferSlice> promise, td::Timestamp timeout, td::BufferSlice data,
td::uint32 flags) override;
void del_local_id(AdnlNodeIdShort local_id) override;
void update_id(AdnlNodeIdFull id) override;

View file

@ -75,6 +75,11 @@ class Adnl : public AdnlSenderInterface {
return 1024 * 8;
}
struct SendFlags {
enum Flags : td::uint32 { direct_only = 1 };
};
virtual void send_message_ex(AdnlNodeIdShort src, AdnlNodeIdShort dst, td::BufferSlice data, td::uint32 flags) = 0;
// adds node to peer table
// used mostly from DHT to avoid loops
virtual void add_peer(AdnlNodeIdShort local_id, AdnlNodeIdFull id, AdnlAddressList addr_list) = 0;