mirror of
https://github.com/ton-blockchain/ton
synced 2025-03-09 15:40:10 +00:00
emergency update
This commit is contained in:
parent
5d846e0aaf
commit
9f351fc29f
87 changed files with 2486 additions and 655 deletions
|
@ -14,7 +14,7 @@
|
|||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with TON Blockchain Library. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
Copyright 2017-2019 Telegram Systems LLP
|
||||
Copyright 2017-2020 Telegram Systems LLP
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with TON Blockchain Library. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
Copyright 2017-2019 Telegram Systems LLP
|
||||
Copyright 2017-2020 Telegram Systems LLP
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
|
|
|
@ -19,6 +19,10 @@
|
|||
#include "adnl-network-manager.hpp"
|
||||
#include "adnl-peer-table.h"
|
||||
|
||||
#include "auto/tl/ton_api.hpp"
|
||||
|
||||
#include "td/utils/overloaded.h"
|
||||
|
||||
namespace ton {
|
||||
|
||||
namespace adnl {
|
||||
|
@ -27,25 +31,84 @@ td::actor::ActorOwn<AdnlNetworkManager> AdnlNetworkManager::create(td::uint16 po
|
|||
return td::actor::create_actor<AdnlNetworkManagerImpl>("NetworkManager", port);
|
||||
}
|
||||
|
||||
void AdnlNetworkManagerImpl::add_listening_udp_port(td::uint16 port) {
|
||||
AdnlNetworkManagerImpl::OutDesc *AdnlNetworkManagerImpl::choose_out_iface(td::uint8 cat, td::uint32 priority) {
|
||||
auto it = out_desc_.upper_bound(priority);
|
||||
while (true) {
|
||||
if (it == out_desc_.begin()) {
|
||||
return nullptr;
|
||||
}
|
||||
it--;
|
||||
|
||||
auto &v = it->second;
|
||||
for (auto &x : v) {
|
||||
if (x.cat_mask.test(cat)) {
|
||||
return &x;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
size_t AdnlNetworkManagerImpl::add_listening_udp_port(td::uint16 port) {
|
||||
auto it = port_2_socket_.find(port);
|
||||
if (it != port_2_socket_.end()) {
|
||||
return it->second;
|
||||
}
|
||||
class Callback : public td::UdpServer::Callback {
|
||||
public:
|
||||
Callback(td::actor::ActorShared<AdnlNetworkManagerImpl> manager) : manager_(std::move(manager)) {
|
||||
Callback(td::actor::ActorShared<AdnlNetworkManagerImpl> manager, size_t idx)
|
||||
: manager_(std::move(manager)), idx_(idx) {
|
||||
}
|
||||
|
||||
private:
|
||||
td::actor::ActorShared<AdnlNetworkManagerImpl> manager_;
|
||||
size_t idx_;
|
||||
void on_udp_message(td::UdpMessage udp_message) override {
|
||||
td::actor::send_closure_later(manager_, &AdnlNetworkManagerImpl::receive_udp_message, std::move(udp_message));
|
||||
td::actor::send_closure_later(manager_, &AdnlNetworkManagerImpl::receive_udp_message, std::move(udp_message),
|
||||
idx_);
|
||||
}
|
||||
};
|
||||
|
||||
auto X = td::UdpServer::create("udp server", port, std::make_unique<Callback>(actor_shared(this)));
|
||||
auto idx = udp_sockets_.size();
|
||||
auto X = td::UdpServer::create("udp server", port, std::make_unique<Callback>(actor_shared(this), idx));
|
||||
X.ensure();
|
||||
udp_servers_.emplace(port, X.move_as_ok());
|
||||
port_2_socket_[port] = idx;
|
||||
udp_sockets_.push_back(UdpSocketDesc{port, X.move_as_ok()});
|
||||
return idx;
|
||||
}
|
||||
|
||||
void AdnlNetworkManagerImpl::receive_udp_message(td::UdpMessage message) {
|
||||
void AdnlNetworkManagerImpl::add_self_addr(td::IPAddress addr, AdnlCategoryMask cat_mask, td::uint32 priority) {
|
||||
auto port = td::narrow_cast<td::uint16>(addr.get_port());
|
||||
size_t idx = add_listening_udp_port(port);
|
||||
add_in_addr(InDesc{port, nullptr, cat_mask}, idx);
|
||||
auto d = OutDesc{port, td::IPAddress{}, nullptr, idx};
|
||||
for (auto &it : out_desc_[priority]) {
|
||||
if (it == d) {
|
||||
it.cat_mask |= cat_mask;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
d.cat_mask = cat_mask;
|
||||
out_desc_[priority].push_back(std::move(d));
|
||||
}
|
||||
|
||||
void AdnlNetworkManagerImpl::add_proxy_addr(td::IPAddress addr, td::uint16 local_port, std::shared_ptr<AdnlProxy> proxy,
|
||||
AdnlCategoryMask cat_mask, td::uint32 priority) {
|
||||
size_t idx = add_listening_udp_port(local_port);
|
||||
add_in_addr(InDesc{local_port, proxy, cat_mask}, idx);
|
||||
auto d = OutDesc{local_port, addr, proxy, idx};
|
||||
for (auto &it : out_desc_[priority]) {
|
||||
if (it == d) {
|
||||
it.cat_mask |= cat_mask;
|
||||
return;
|
||||
}
|
||||
}
|
||||
d.cat_mask = cat_mask;
|
||||
proxy_register(d);
|
||||
out_desc_[priority].push_back(std::move(d));
|
||||
}
|
||||
|
||||
void AdnlNetworkManagerImpl::receive_udp_message(td::UdpMessage message, size_t idx) {
|
||||
if (!callback_) {
|
||||
LOG(ERROR) << this << ": dropping IN message [?->?]: peer table unitialized";
|
||||
return;
|
||||
|
@ -54,6 +117,96 @@ void AdnlNetworkManagerImpl::receive_udp_message(td::UdpMessage message) {
|
|||
VLOG(ADNL_WARNING) << this << ": dropping ERROR message: " << message.error;
|
||||
return;
|
||||
}
|
||||
if (message.data.size() < 32) {
|
||||
VLOG(ADNL_WARNING) << this << ": received too small proxy packet of size " << message.data.size();
|
||||
return;
|
||||
}
|
||||
if (message.data.size() >= get_mtu() + 128) {
|
||||
VLOG(ADNL_NOTICE) << this << ": received huge packet of size " << message.data.size();
|
||||
}
|
||||
CHECK(idx < udp_sockets_.size());
|
||||
auto &socket = udp_sockets_[idx];
|
||||
AdnlCategoryMask cat_mask;
|
||||
bool from_proxy = false;
|
||||
if (socket.allow_proxy) {
|
||||
td::Bits256 x;
|
||||
x.as_slice().copy_from(message.data.as_slice().truncate(32));
|
||||
auto it = proxy_addrs_.find(x);
|
||||
if (it != proxy_addrs_.end()) {
|
||||
from_proxy = true;
|
||||
CHECK(it->second < in_desc_.size());
|
||||
auto &proxy_iface = in_desc_[it->second];
|
||||
CHECK(proxy_iface.is_proxy());
|
||||
auto R = in_desc_[it->second].proxy->decrypt(std::move(message.data));
|
||||
if (R.is_error()) {
|
||||
VLOG(ADNL_WARNING) << this << ": failed to decrypt proxy mesage: " << R.move_as_error();
|
||||
return;
|
||||
}
|
||||
auto packet = R.move_as_ok();
|
||||
if (packet.flags & 1) {
|
||||
message.address.init_host_port(td::IPAddress::ipv4_to_str(packet.ip), packet.port).ensure();
|
||||
} else {
|
||||
message.address = td::IPAddress{};
|
||||
}
|
||||
if ((packet.flags & 6) == 6) {
|
||||
if (proxy_iface.received.packet_is_delivered(packet.adnl_start_time, packet.seqno)) {
|
||||
VLOG(ADNL_WARNING) << this << ": dropping duplicate proxy packet";
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (packet.flags & 8) {
|
||||
if (packet.date < td::Clocks::system() - 60 || packet.date > td::Clocks::system() + 60) {
|
||||
VLOG(ADNL_WARNING) << this << ": dropping proxy packet: bad time " << packet.date;
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (!(packet.flags & (1 << 16))) {
|
||||
VLOG(ADNL_WARNING) << this << ": dropping proxy packet: packet has outbound flag";
|
||||
return;
|
||||
}
|
||||
if (packet.flags & (1 << 17)) {
|
||||
auto F = fetch_tl_object<ton_api::adnl_ProxyControlPacket>(std::move(packet.data), true);
|
||||
if (F.is_error()) {
|
||||
VLOG(ADNL_WARNING) << this << ": dropping proxy packet: bad control packet";
|
||||
return;
|
||||
}
|
||||
ton_api::downcast_call(*F.move_as_ok().get(),
|
||||
td::overloaded(
|
||||
[&](const ton_api::adnl_proxyControlPacketPing &f) {
|
||||
auto &v = *proxy_iface.out_desc;
|
||||
auto data =
|
||||
create_serialize_tl_object<ton_api::adnl_proxyControlPacketPong>(f.id_);
|
||||
AdnlProxy::Packet p;
|
||||
p.flags = 6 | (1 << 17);
|
||||
p.ip = 0;
|
||||
p.port = 0;
|
||||
p.data = std::move(data);
|
||||
p.adnl_start_time = Adnl::adnl_start_time();
|
||||
p.seqno = ++v.out_seqno;
|
||||
|
||||
auto enc = v.proxy->encrypt(std::move(p));
|
||||
|
||||
td::UdpMessage M;
|
||||
M.address = v.proxy_addr;
|
||||
M.data = std::move(enc);
|
||||
|
||||
td::actor::send_closure(socket.server, &td::UdpServer::send, std::move(M));
|
||||
},
|
||||
[&](const ton_api::adnl_proxyControlPacketPong &f) {},
|
||||
[&](const ton_api::adnl_proxyControlPacketRegister &f) {}));
|
||||
return;
|
||||
}
|
||||
message.data = std::move(packet.data);
|
||||
cat_mask = in_desc_[it->second].cat_mask;
|
||||
}
|
||||
}
|
||||
if (!from_proxy) {
|
||||
if (socket.in_desc == std::numeric_limits<size_t>::max()) {
|
||||
VLOG(ADNL_WARNING) << this << ": received bad packet to proxy-only listenung port";
|
||||
return;
|
||||
}
|
||||
cat_mask = in_desc_[socket.in_desc].cat_mask;
|
||||
}
|
||||
if (message.data.size() >= get_mtu()) {
|
||||
VLOG(ADNL_NOTICE) << this << ": received huge packet of size " << message.data.size();
|
||||
}
|
||||
|
@ -63,49 +216,81 @@ void AdnlNetworkManagerImpl::receive_udp_message(td::UdpMessage message) {
|
|||
}
|
||||
|
||||
VLOG(ADNL_EXTRA_DEBUG) << this << ": received message of size " << message.data.size();
|
||||
callback_->receive_packet(message.address, std::move(message.data));
|
||||
callback_->receive_packet(message.address, cat_mask, std::move(message.data));
|
||||
}
|
||||
|
||||
void AdnlNetworkManagerImpl::send_udp_packet(AdnlNodeIdShort src_id, AdnlNodeIdShort dst_id, td::IPAddress dst_addr,
|
||||
td::uint32 priority, td::BufferSlice data) {
|
||||
auto randseed = 1; // use DST?
|
||||
while (priority > 0) {
|
||||
if (out_desc_[priority].size() > 0) {
|
||||
break;
|
||||
}
|
||||
priority--;
|
||||
}
|
||||
if (out_desc_[priority].size() == 0) {
|
||||
VLOG(ADNL_WARNING) << this << ": dropping OUT message [" << src_id << "->" << dst_id << "]: no out desc";
|
||||
auto it = adnl_id_2_cat_.find(src_id);
|
||||
if (it == adnl_id_2_cat_.end()) {
|
||||
VLOG(ADNL_WARNING) << this << ": dropping OUT message [" << src_id << "->" << dst_id << "]: unknown src";
|
||||
return;
|
||||
}
|
||||
|
||||
auto &dv = out_desc_[priority];
|
||||
auto &v = dv[randseed % dv.size()];
|
||||
auto out = choose_out_iface(it->second, priority);
|
||||
if (!out) {
|
||||
VLOG(ADNL_WARNING) << this << ": dropping OUT message [" << src_id << "->" << dst_id << "]: no out rules";
|
||||
return;
|
||||
}
|
||||
|
||||
auto &v = *out;
|
||||
auto &socket = udp_sockets_[v.socket_idx];
|
||||
|
||||
if (!v.is_proxy()) {
|
||||
auto it = udp_servers_.find(static_cast<td::uint16>(v.addr.get_port()));
|
||||
CHECK(it != udp_servers_.end());
|
||||
|
||||
td::UdpMessage M;
|
||||
M.address = dst_addr;
|
||||
M.data = std::move(data);
|
||||
|
||||
CHECK(M.data.size() <= get_mtu());
|
||||
|
||||
td::actor::send_closure(it->second, &td::UdpServer::send, std::move(M));
|
||||
td::actor::send_closure(socket.server, &td::UdpServer::send, std::move(M));
|
||||
} else {
|
||||
auto it = udp_servers_.find(out_udp_port_);
|
||||
CHECK(it != udp_servers_.end());
|
||||
AdnlProxy::Packet p;
|
||||
p.flags = 7;
|
||||
p.ip = dst_addr.get_ipv4();
|
||||
p.port = static_cast<td::uint16>(dst_addr.get_port());
|
||||
p.data = std::move(data);
|
||||
p.adnl_start_time = Adnl::adnl_start_time();
|
||||
p.seqno = ++v.out_seqno;
|
||||
|
||||
auto enc = v.proxy->encrypt(
|
||||
AdnlProxy::Packet{dst_addr.get_ipv4(), static_cast<td::uint16>(dst_addr.get_port()), std::move(data)});
|
||||
auto enc = v.proxy->encrypt(std::move(p));
|
||||
|
||||
td::UdpMessage M;
|
||||
M.address = v.addr;
|
||||
M.address = v.proxy_addr;
|
||||
M.data = std::move(enc);
|
||||
|
||||
td::actor::send_closure(it->second, &td::UdpServer::send, std::move(M));
|
||||
td::actor::send_closure(socket.server, &td::UdpServer::send, std::move(M));
|
||||
}
|
||||
}
|
||||
|
||||
void AdnlNetworkManagerImpl::proxy_register(OutDesc &desc) {
|
||||
auto data = create_serialize_tl_object<ton_api::adnl_proxyControlPacketRegister>(0, 0);
|
||||
AdnlProxy::Packet p;
|
||||
p.flags = 6 | (1 << 17);
|
||||
p.ip = 0;
|
||||
p.port = 0;
|
||||
p.data = std::move(data);
|
||||
p.adnl_start_time = Adnl::adnl_start_time();
|
||||
p.seqno = ++desc.out_seqno;
|
||||
|
||||
auto enc = desc.proxy->encrypt(std::move(p));
|
||||
|
||||
td::UdpMessage M;
|
||||
M.address = desc.proxy_addr;
|
||||
M.data = std::move(enc);
|
||||
|
||||
auto &socket = udp_sockets_[desc.socket_idx];
|
||||
td::actor::send_closure(socket.server, &td::UdpServer::send, std::move(M));
|
||||
}
|
||||
|
||||
void AdnlNetworkManagerImpl::alarm() {
|
||||
alarm_timestamp() = td::Timestamp::in(60.0);
|
||||
for (auto &vec : out_desc_) {
|
||||
for (auto &desc : vec.second) {
|
||||
if (desc.is_proxy()) {
|
||||
proxy_register(desc);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with TON Blockchain Library. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
Copyright 2017-2019 Telegram Systems LLP
|
||||
Copyright 2017-2020 Telegram Systems LLP
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
|
@ -26,6 +26,8 @@
|
|||
#include "adnl-node-id.hpp"
|
||||
#include "adnl-proxy-types.h"
|
||||
|
||||
#include <bitset>
|
||||
|
||||
namespace td {
|
||||
class UdpServer;
|
||||
}
|
||||
|
@ -36,6 +38,8 @@ namespace adnl {
|
|||
|
||||
class AdnlPeerTable;
|
||||
|
||||
using AdnlCategoryMask = std::bitset<256>;
|
||||
|
||||
class AdnlNetworkConnection : public td::actor::Actor {
|
||||
public:
|
||||
class Callback {
|
||||
|
@ -56,7 +60,7 @@ class AdnlNetworkManager : public td::actor::Actor {
|
|||
public:
|
||||
virtual ~Callback() = default;
|
||||
//virtual void receive_packet(td::IPAddress addr, ConnHandle conn_handle, td::BufferSlice data) = 0;
|
||||
virtual void receive_packet(td::IPAddress addr, td::BufferSlice data) = 0;
|
||||
virtual void receive_packet(td::IPAddress addr, AdnlCategoryMask cat_mask, td::BufferSlice data) = 0;
|
||||
};
|
||||
static td::actor::ActorOwn<AdnlNetworkManager> create(td::uint16 out_port);
|
||||
|
||||
|
@ -64,14 +68,16 @@ class AdnlNetworkManager : public td::actor::Actor {
|
|||
|
||||
virtual void install_callback(std::unique_ptr<Callback> callback) = 0;
|
||||
|
||||
virtual void add_self_addr(td::IPAddress addr, td::uint32 priority) = 0;
|
||||
virtual void add_proxy_addr(td::IPAddress addr, std::shared_ptr<AdnlProxy> proxy, td::uint32 priority) = 0;
|
||||
virtual void add_self_addr(td::IPAddress addr, AdnlCategoryMask cat_mask, td::uint32 priority) = 0;
|
||||
virtual void add_proxy_addr(td::IPAddress addr, td::uint16 local_port, std::shared_ptr<AdnlProxy> proxy,
|
||||
AdnlCategoryMask cat_mask, td::uint32 priority) = 0;
|
||||
virtual void send_udp_packet(AdnlNodeIdShort src_id, AdnlNodeIdShort dst_id, td::IPAddress dst_addr,
|
||||
td::uint32 priority, td::BufferSlice data) = 0;
|
||||
//virtual void send_tcp_packet(AdnlNodeIdShort src_id, AdnlNodeIdShort dst_id, td::IPAddress dst_addr,
|
||||
// td::uint32 priority, td::BufferSlice data) = 0;
|
||||
//virtual void send_answer_packet(AdnlNodeIdShort src_id, AdnlNodeIdShort dst_id, td::IPAddress dst_addr,
|
||||
// ConnHandle conn_handle, td::uint32 priority, td::BufferSlice data) = 0;
|
||||
virtual void set_local_id_category(AdnlNodeIdShort id, td::uint8 cat) = 0;
|
||||
|
||||
static constexpr td::uint32 get_mtu() {
|
||||
return 1440;
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with TON Blockchain Library. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
Copyright 2017-2019 Telegram Systems LLP
|
||||
Copyright 2017-2020 Telegram Systems LLP
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
|
@ -25,6 +25,7 @@
|
|||
|
||||
#include "td/actor/PromiseFuture.h"
|
||||
#include "adnl-network-manager.h"
|
||||
#include "adnl-received-mask.h"
|
||||
|
||||
#include <map>
|
||||
|
||||
|
@ -41,16 +42,61 @@ class AdnlPeerTable;
|
|||
class AdnlNetworkManagerImpl : public AdnlNetworkManager {
|
||||
public:
|
||||
struct OutDesc {
|
||||
td::IPAddress addr;
|
||||
td::uint16 port;
|
||||
td::IPAddress proxy_addr;
|
||||
std::shared_ptr<AdnlProxy> proxy;
|
||||
size_t socket_idx;
|
||||
td::int64 out_seqno{0};
|
||||
AdnlCategoryMask cat_mask{0};
|
||||
|
||||
bool is_proxy() const {
|
||||
return proxy != nullptr;
|
||||
}
|
||||
bool operator==(const OutDesc &with) const {
|
||||
return addr == with.addr && is_proxy() == with.is_proxy();
|
||||
if (port != with.port) {
|
||||
return false;
|
||||
}
|
||||
if (!is_proxy()) {
|
||||
return !with.is_proxy();
|
||||
}
|
||||
if (!with.is_proxy()) {
|
||||
return false;
|
||||
}
|
||||
return proxy_addr == with.proxy_addr && proxy->id() == with.proxy->id();
|
||||
}
|
||||
};
|
||||
struct InDesc {
|
||||
td::uint16 port;
|
||||
std::shared_ptr<AdnlProxy> proxy;
|
||||
AdnlCategoryMask cat_mask;
|
||||
AdnlReceivedMaskVersion received{};
|
||||
OutDesc *out_desc = nullptr;
|
||||
bool is_proxy() const {
|
||||
return proxy != nullptr;
|
||||
}
|
||||
bool operator==(const InDesc &with) const {
|
||||
if (port != with.port) {
|
||||
return false;
|
||||
}
|
||||
if (!is_proxy()) {
|
||||
return !with.is_proxy();
|
||||
}
|
||||
if (!with.is_proxy()) {
|
||||
return false;
|
||||
}
|
||||
return proxy->id() == with.proxy->id();
|
||||
}
|
||||
};
|
||||
struct UdpSocketDesc {
|
||||
UdpSocketDesc(td::uint16 port, td::actor::ActorOwn<td::UdpServer> server) : port(port), server(std::move(server)) {
|
||||
}
|
||||
td::uint16 port;
|
||||
td::actor::ActorOwn<td::UdpServer> server;
|
||||
size_t in_desc{std::numeric_limits<size_t>::max()};
|
||||
bool allow_proxy{false};
|
||||
};
|
||||
|
||||
OutDesc *choose_out_iface(td::uint8 cat, td::uint32 priority);
|
||||
|
||||
AdnlNetworkManagerImpl(td::uint16 out_udp_port) : out_udp_port_(out_udp_port) {
|
||||
}
|
||||
|
@ -59,45 +105,60 @@ class AdnlNetworkManagerImpl : public AdnlNetworkManager {
|
|||
callback_ = std::move(callback);
|
||||
}
|
||||
|
||||
void add_self_addr(td::IPAddress addr, td::uint32 priority) override {
|
||||
auto x = OutDesc{addr, nullptr};
|
||||
auto &v = out_desc_[priority];
|
||||
for (auto &y : v) {
|
||||
if (x == y) {
|
||||
void alarm() override;
|
||||
void start_up() override {
|
||||
alarm_timestamp() = td::Timestamp::in(60.0);
|
||||
}
|
||||
|
||||
void add_in_addr(InDesc desc, size_t socket_idx) {
|
||||
for (size_t idx = 0; idx < in_desc_.size(); idx++) {
|
||||
if (in_desc_[idx] == desc) {
|
||||
in_desc_[idx].cat_mask |= desc.cat_mask;
|
||||
return;
|
||||
}
|
||||
}
|
||||
out_desc_[priority].push_back(std::move(x));
|
||||
add_listening_udp_port(static_cast<td::uint16>(addr.get_port()));
|
||||
}
|
||||
void add_proxy_addr(td::IPAddress addr, std::shared_ptr<AdnlProxy> proxy, td::uint32 priority) override {
|
||||
auto x = OutDesc{addr, std::move(proxy)};
|
||||
auto &v = out_desc_[priority];
|
||||
for (auto &y : v) {
|
||||
if (x == y) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
out_desc_[priority].push_back(std::move(x));
|
||||
if (!udp_servers_.count(out_udp_port_)) {
|
||||
add_listening_udp_port(out_udp_port_);
|
||||
if (desc.is_proxy()) {
|
||||
udp_sockets_[socket_idx].allow_proxy = true;
|
||||
proxy_addrs_[desc.proxy->id()] = in_desc_.size();
|
||||
} else {
|
||||
CHECK(udp_sockets_[socket_idx].in_desc == std::numeric_limits<size_t>::max());
|
||||
udp_sockets_[socket_idx].in_desc = in_desc_.size();
|
||||
}
|
||||
in_desc_.push_back(std::move(desc));
|
||||
}
|
||||
|
||||
void add_self_addr(td::IPAddress addr, AdnlCategoryMask cat_mask, td::uint32 priority) override;
|
||||
void add_proxy_addr(td::IPAddress addr, td::uint16 local_port, std::shared_ptr<AdnlProxy> proxy,
|
||||
AdnlCategoryMask cat_mask, td::uint32 priority) override;
|
||||
void send_udp_packet(AdnlNodeIdShort src_id, AdnlNodeIdShort dst_id, td::IPAddress dst_addr, td::uint32 priority,
|
||||
td::BufferSlice data) override;
|
||||
|
||||
void add_listening_udp_port(td::uint16 port);
|
||||
void receive_udp_message(td::UdpMessage message);
|
||||
void set_local_id_category(AdnlNodeIdShort id, td::uint8 cat) override {
|
||||
if (cat == 255) {
|
||||
adnl_id_2_cat_.erase(id);
|
||||
} else {
|
||||
adnl_id_2_cat_[id] = cat;
|
||||
}
|
||||
}
|
||||
|
||||
size_t add_listening_udp_port(td::uint16 port);
|
||||
void receive_udp_message(td::UdpMessage message, size_t idx);
|
||||
void proxy_register(OutDesc &desc);
|
||||
|
||||
private:
|
||||
std::unique_ptr<Callback> callback_;
|
||||
|
||||
std::map<td::uint32, std::vector<OutDesc>> out_desc_;
|
||||
std::vector<InDesc> in_desc_;
|
||||
std::map<td::Bits256, size_t> proxy_addrs_;
|
||||
|
||||
td::uint64 received_messages_ = 0;
|
||||
td::uint64 sent_messages_ = 0;
|
||||
|
||||
std::map<td::uint16, td::actor::ActorOwn<td::UdpServer>> udp_servers_;
|
||||
std::vector<UdpSocketDesc> udp_sockets_;
|
||||
std::map<td::uint16, size_t> port_2_socket_;
|
||||
|
||||
std::map<AdnlNodeIdShort, td::uint8> adnl_id_2_cat_;
|
||||
|
||||
td::uint16 out_udp_port_;
|
||||
};
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
#include "utils.hpp"
|
||||
#include "adnl-query.h"
|
||||
#include "adnl-ext-client.h"
|
||||
#include "adnl-tunnel.h"
|
||||
|
||||
namespace ton {
|
||||
|
||||
|
@ -49,7 +50,7 @@ td::actor::ActorOwn<Adnl> Adnl::create(std::string db, td::actor::ActorId<keyrin
|
|||
return td::actor::ActorOwn<Adnl>(td::actor::create_actor<AdnlPeerTableImpl>("PeerTable", db, keyring));
|
||||
}
|
||||
|
||||
void AdnlPeerTableImpl::receive_packet(td::IPAddress addr, td::BufferSlice data) {
|
||||
void AdnlPeerTableImpl::receive_packet(td::IPAddress addr, AdnlCategoryMask cat_mask, td::BufferSlice data) {
|
||||
if (data.size() < 32) {
|
||||
VLOG(ADNL_WARNING) << this << ": dropping IN message [?->?]: message too short: len=" << data.size();
|
||||
return;
|
||||
|
@ -60,14 +61,22 @@ void AdnlPeerTableImpl::receive_packet(td::IPAddress addr, td::BufferSlice data)
|
|||
|
||||
auto it = local_ids_.find(dst);
|
||||
if (it != local_ids_.end()) {
|
||||
td::actor::send_closure(it->second.first, &AdnlLocalId::receive, addr, std::move(data));
|
||||
if (!cat_mask.test(it->second.cat)) {
|
||||
VLOG(ADNL_WARNING) << this << ": dropping IN message [?->" << dst << "]: category mismatch";
|
||||
return;
|
||||
}
|
||||
td::actor::send_closure(it->second.local_id, &AdnlLocalId::receive, addr, std::move(data));
|
||||
return;
|
||||
}
|
||||
|
||||
AdnlChannelIdShort dst_chan_id{dst.pubkey_hash()};
|
||||
auto it2 = channels_.find(dst_chan_id);
|
||||
if (it2 != channels_.end()) {
|
||||
td::actor::send_closure(it2->second, &AdnlChannel::receive, addr, std::move(data));
|
||||
if (!cat_mask.test(it2->second.second)) {
|
||||
VLOG(ADNL_WARNING) << this << ": dropping IN message to channel [?->" << dst << "]: category mismatch";
|
||||
return;
|
||||
}
|
||||
td::actor::send_closure(it2->second.first, &AdnlChannel::receive, addr, std::move(data));
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -109,7 +118,7 @@ void AdnlPeerTableImpl::receive_decrypted_packet(AdnlNodeIdShort dst, AdnlPacket
|
|||
<< "]: unknown dst (but how did we decrypt message?)";
|
||||
return;
|
||||
}
|
||||
td::actor::send_closure(it->second, &AdnlPeer::receive_packet, dst, it2->second.second, it2->second.first.get(),
|
||||
td::actor::send_closure(it->second, &AdnlPeer::receive_packet, dst, it2->second.mode, it2->second.local_id.get(),
|
||||
std::move(packet));
|
||||
}
|
||||
|
||||
|
@ -127,8 +136,8 @@ void AdnlPeerTableImpl::add_peer(AdnlNodeIdShort local_id, AdnlNodeIdFull id, Ad
|
|||
}
|
||||
td::actor::send_closure(it->second, &AdnlPeer::update_id, std::move(id));
|
||||
if (!addr_list.empty()) {
|
||||
td::actor::send_closure(it->second, &AdnlPeer::update_addr_list, local_id, it2->second.second,
|
||||
it2->second.first.get(), std::move(addr_list));
|
||||
td::actor::send_closure(it->second, &AdnlPeer::update_addr_list, local_id, it2->second.mode,
|
||||
it2->second.local_id.get(), std::move(addr_list));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -152,7 +161,7 @@ void AdnlPeerTableImpl::send_message_in(AdnlNodeIdShort src, AdnlNodeIdShort dst
|
|||
return;
|
||||
}
|
||||
|
||||
td::actor::send_closure(it->second, &AdnlPeer::send_one_message, src, it2->second.second, it2->second.first.get(),
|
||||
td::actor::send_closure(it->second, &AdnlPeer::send_one_message, src, it2->second.mode, it2->second.local_id.get(),
|
||||
OutboundAdnlMessage{std::move(message), flags});
|
||||
}
|
||||
|
||||
|
@ -185,23 +194,32 @@ void AdnlPeerTableImpl::send_query(AdnlNodeIdShort src, AdnlNodeIdShort dst, std
|
|||
return;
|
||||
}
|
||||
|
||||
td::actor::send_closure(it->second, &AdnlPeer::send_query, src, it2->second.second, it2->second.first.get(), name,
|
||||
td::actor::send_closure(it->second, &AdnlPeer::send_query, src, it2->second.mode, it2->second.local_id.get(), name,
|
||||
std::move(promise), timeout, std::move(data), 0);
|
||||
}
|
||||
|
||||
void AdnlPeerTableImpl::add_id_ex(AdnlNodeIdFull id, AdnlAddressList addr_list, td::uint32 mode) {
|
||||
void AdnlPeerTableImpl::add_id_ex(AdnlNodeIdFull id, AdnlAddressList addr_list, td::uint8 cat, td::uint32 mode) {
|
||||
auto a = id.compute_short_id();
|
||||
VLOG(ADNL_INFO) << "adnl: adding local id " << a;
|
||||
|
||||
auto it = local_ids_.find(a);
|
||||
|
||||
if (it != local_ids_.end()) {
|
||||
td::actor::send_closure(it->second.first, &AdnlLocalId::update_address_list, std::move(addr_list));
|
||||
if (it->second.cat != cat) {
|
||||
it->second.cat = cat;
|
||||
if (!network_manager_.empty()) {
|
||||
td::actor::send_closure(network_manager_, &AdnlNetworkManager::set_local_id_category, a, cat);
|
||||
}
|
||||
}
|
||||
td::actor::send_closure(it->second.local_id, &AdnlLocalId::update_address_list, std::move(addr_list));
|
||||
} else {
|
||||
local_ids_.emplace(
|
||||
a, std::make_pair(td::actor::create_actor<AdnlLocalId>("localid", std::move(id), std::move(addr_list), mode,
|
||||
actor_id(this), keyring_, dht_node_),
|
||||
mode));
|
||||
a, LocalIdInfo{td::actor::create_actor<AdnlLocalId>("localid", std::move(id), std::move(addr_list), mode,
|
||||
actor_id(this), keyring_, dht_node_),
|
||||
cat, mode});
|
||||
if (!network_manager_.empty()) {
|
||||
td::actor::send_closure(network_manager_, &AdnlNetworkManager::set_local_id_category, a, cat);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -215,14 +233,14 @@ void AdnlPeerTableImpl::subscribe(AdnlNodeIdShort dst, std::string prefix, std::
|
|||
auto it = local_ids_.find(dst);
|
||||
LOG_CHECK(it != local_ids_.end()) << "dst=" << dst;
|
||||
|
||||
td::actor::send_closure(it->second.first, &AdnlLocalId::subscribe, prefix, std::move(callback));
|
||||
td::actor::send_closure(it->second.local_id, &AdnlLocalId::subscribe, prefix, std::move(callback));
|
||||
}
|
||||
|
||||
void AdnlPeerTableImpl::unsubscribe(AdnlNodeIdShort dst, std::string prefix) {
|
||||
auto it = local_ids_.find(dst);
|
||||
|
||||
if (it != local_ids_.end()) {
|
||||
td::actor::send_closure(it->second.first, &AdnlLocalId::unsubscribe, prefix);
|
||||
td::actor::send_closure(it->second.local_id, &AdnlLocalId::unsubscribe, prefix);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -233,7 +251,7 @@ void AdnlPeerTableImpl::register_dht_node(td::actor::ActorId<dht::Dht> dht_node)
|
|||
td::actor::send_closure(peer.second, &AdnlPeer::update_dht_node, dht_node_);
|
||||
}
|
||||
for (auto &local_id : local_ids_) {
|
||||
td::actor::send_closure(local_id.second.first, &AdnlLocalId::update_dht_node, dht_node_);
|
||||
td::actor::send_closure(local_id.second.local_id, &AdnlLocalId::update_dht_node, dht_node_);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -242,8 +260,8 @@ void AdnlPeerTableImpl::register_network_manager(td::actor::ActorId<AdnlNetworkM
|
|||
|
||||
class Cb : public AdnlNetworkManager::Callback {
|
||||
public:
|
||||
void receive_packet(td::IPAddress addr, td::BufferSlice data) override {
|
||||
td::actor::send_closure(id_, &AdnlPeerTableImpl::receive_packet, addr, std::move(data));
|
||||
void receive_packet(td::IPAddress addr, AdnlCategoryMask cat_mask, td::BufferSlice data) override {
|
||||
td::actor::send_closure(id_, &AdnlPeerTableImpl::receive_packet, addr, std::move(cat_mask), std::move(data));
|
||||
}
|
||||
Cb(td::actor::ActorId<AdnlPeerTableImpl> id) : id_(id) {
|
||||
}
|
||||
|
@ -254,6 +272,10 @@ void AdnlPeerTableImpl::register_network_manager(td::actor::ActorId<AdnlNetworkM
|
|||
|
||||
auto cb = std::make_unique<Cb>(actor_id(this));
|
||||
td::actor::send_closure(network_manager_, &AdnlNetworkManager::install_callback, std::move(cb));
|
||||
|
||||
for (auto &id : local_ids_) {
|
||||
td::actor::send_closure(network_manager_, &AdnlNetworkManager::set_local_id_category, id.first, id.second.cat);
|
||||
}
|
||||
}
|
||||
|
||||
void AdnlPeerTableImpl::get_addr_list(AdnlNodeIdShort id, td::Promise<AdnlAddressList> promise) {
|
||||
|
@ -262,7 +284,7 @@ void AdnlPeerTableImpl::get_addr_list(AdnlNodeIdShort id, td::Promise<AdnlAddres
|
|||
promise.set_error(td::Status::Error(ErrorCode::notready));
|
||||
return;
|
||||
}
|
||||
td::actor::send_closure(it->second.first, &AdnlLocalId::get_addr_list_async, std::move(promise));
|
||||
td::actor::send_closure(it->second.local_id, &AdnlLocalId::get_addr_list_async, std::move(promise));
|
||||
}
|
||||
|
||||
void AdnlPeerTableImpl::get_self_node(AdnlNodeIdShort id, td::Promise<AdnlNode> promise) {
|
||||
|
@ -271,11 +293,14 @@ void AdnlPeerTableImpl::get_self_node(AdnlNodeIdShort id, td::Promise<AdnlNode>
|
|||
promise.set_error(td::Status::Error(ErrorCode::notready));
|
||||
return;
|
||||
}
|
||||
td::actor::send_closure(it->second.first, &AdnlLocalId::get_self_node, std::move(promise));
|
||||
td::actor::send_closure(it->second.local_id, &AdnlLocalId::get_self_node, std::move(promise));
|
||||
}
|
||||
|
||||
void AdnlPeerTableImpl::register_channel(AdnlChannelIdShort id, td::actor::ActorId<AdnlChannel> channel) {
|
||||
auto success = channels_.emplace(id, channel).second;
|
||||
void AdnlPeerTableImpl::register_channel(AdnlChannelIdShort id, AdnlNodeIdShort local_id,
|
||||
td::actor::ActorId<AdnlChannel> channel) {
|
||||
auto it = local_ids_.find(local_id);
|
||||
auto cat = (it != local_ids_.end()) ? it->second.cat : 255;
|
||||
auto success = channels_.emplace(id, std::make_pair(channel, cat)).second;
|
||||
CHECK(success);
|
||||
}
|
||||
|
||||
|
@ -317,14 +342,14 @@ AdnlPeerTableImpl::AdnlPeerTableImpl(std::string db_root, td::actor::ActorId<key
|
|||
void AdnlPeerTableImpl::deliver(AdnlNodeIdShort src, AdnlNodeIdShort dst, td::BufferSlice data) {
|
||||
auto it = local_ids_.find(dst);
|
||||
if (it != local_ids_.end()) {
|
||||
td::actor::send_closure(it->second.first, &AdnlLocalId::deliver, src, std::move(data));
|
||||
td::actor::send_closure(it->second.local_id, &AdnlLocalId::deliver, src, std::move(data));
|
||||
}
|
||||
}
|
||||
void AdnlPeerTableImpl::deliver_query(AdnlNodeIdShort src, AdnlNodeIdShort dst, td::BufferSlice data,
|
||||
td::Promise<td::BufferSlice> promise) {
|
||||
auto it = local_ids_.find(dst);
|
||||
if (it != local_ids_.end()) {
|
||||
td::actor::send_closure(it->second.first, &AdnlLocalId::deliver_query, src, std::move(data), std::move(promise));
|
||||
td::actor::send_closure(it->second.local_id, &AdnlLocalId::deliver_query, src, std::move(data), std::move(promise));
|
||||
} else {
|
||||
LOG(WARNING) << "deliver query: unknown dst " << dst;
|
||||
promise.set_error(td::Status::Error(ErrorCode::notready, "cannot deliver: unknown DST"));
|
||||
|
@ -335,7 +360,7 @@ void AdnlPeerTableImpl::decrypt_message(AdnlNodeIdShort dst, td::BufferSlice dat
|
|||
td::Promise<td::BufferSlice> promise) {
|
||||
auto it = local_ids_.find(dst);
|
||||
if (it != local_ids_.end()) {
|
||||
td::actor::send_closure(it->second.first, &AdnlLocalId::decrypt_message, std::move(data), std::move(promise));
|
||||
td::actor::send_closure(it->second.local_id, &AdnlLocalId::decrypt_message, std::move(data), std::move(promise));
|
||||
} else {
|
||||
LOG(WARNING) << "decrypt message: unknown dst " << dst;
|
||||
promise.set_error(td::Status::Error(ErrorCode::notready, "cannot decrypt: unknown DST"));
|
||||
|
@ -347,6 +372,10 @@ void AdnlPeerTableImpl::create_ext_server(std::vector<AdnlNodeIdShort> ids, std:
|
|||
promise.set_value(AdnlExtServerCreator::create(actor_id(this), std::move(ids), std::move(ports)));
|
||||
}
|
||||
|
||||
void AdnlPeerTableImpl::create_tunnel(AdnlNodeIdShort dst, td::uint32 size,
|
||||
td::Promise<std::pair<td::actor::ActorOwn<AdnlTunnel>, AdnlAddress>> promise) {
|
||||
}
|
||||
|
||||
} // namespace adnl
|
||||
|
||||
} // namespace ton
|
||||
|
|
|
@ -89,11 +89,12 @@ class AdnlPeerTable : public Adnl {
|
|||
|
||||
virtual void answer_query(AdnlNodeIdShort src, AdnlNodeIdShort dst, AdnlQueryId query_id, td::BufferSlice data) = 0;
|
||||
|
||||
virtual void receive_packet(td::IPAddress addr, td::BufferSlice data) = 0;
|
||||
virtual void receive_packet(td::IPAddress addr, AdnlCategoryMask cat_mask, 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, td::uint32 flags) = 0;
|
||||
|
||||
virtual void register_channel(AdnlChannelIdShort id, td::actor::ActorId<AdnlChannel> channel) = 0;
|
||||
virtual void register_channel(AdnlChannelIdShort id, AdnlNodeIdShort local_id,
|
||||
td::actor::ActorId<AdnlChannel> channel) = 0;
|
||||
virtual void unregister_channel(AdnlChannelIdShort id) = 0;
|
||||
|
||||
virtual void add_static_node(AdnlNode node) = 0;
|
||||
|
|
|
@ -43,7 +43,7 @@ class AdnlPeerTableImpl : public AdnlPeerTable {
|
|||
void add_peer(AdnlNodeIdShort local_id, AdnlNodeIdFull id, AdnlAddressList addr_list) override;
|
||||
void add_static_nodes_from_config(AdnlNodesList nodes) override;
|
||||
|
||||
void receive_packet(td::IPAddress addr, td::BufferSlice data) override;
|
||||
void receive_packet(td::IPAddress addr, AdnlCategoryMask cat_mask, td::BufferSlice data) override;
|
||||
void receive_decrypted_packet(AdnlNodeIdShort dst, AdnlPacket data) 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 {
|
||||
|
@ -64,7 +64,7 @@ class AdnlPeerTableImpl : public AdnlPeerTable {
|
|||
td::Timestamp timeout, td::BufferSlice data, td::uint64 max_answer_size) override {
|
||||
send_query(src, dst, name, std::move(promise), timeout, std::move(data));
|
||||
}
|
||||
void add_id_ex(AdnlNodeIdFull id, AdnlAddressList addr_list, td::uint32 mode) override;
|
||||
void add_id_ex(AdnlNodeIdFull id, AdnlAddressList addr_list, td::uint8 cat, td::uint32 mode) override;
|
||||
void del_id(AdnlNodeIdShort id, td::Promise<td::Unit> promise) override;
|
||||
void subscribe(AdnlNodeIdShort dst, std::string prefix, std::unique_ptr<Callback> callback) override;
|
||||
void unsubscribe(AdnlNodeIdShort dst, std::string prefix) override;
|
||||
|
@ -73,7 +73,8 @@ class AdnlPeerTableImpl : public AdnlPeerTable {
|
|||
void get_addr_list(AdnlNodeIdShort id, td::Promise<AdnlAddressList> promise) override;
|
||||
void get_self_node(AdnlNodeIdShort id, td::Promise<AdnlNode> promise) override;
|
||||
void start_up() override;
|
||||
void register_channel(AdnlChannelIdShort id, td::actor::ActorId<AdnlChannel> channel) override;
|
||||
void register_channel(AdnlChannelIdShort id, AdnlNodeIdShort local_id,
|
||||
td::actor::ActorId<AdnlChannel> channel) override;
|
||||
void unregister_channel(AdnlChannelIdShort id) override;
|
||||
|
||||
void write_new_addr_list_to_db(AdnlNodeIdShort local_id, AdnlNodeIdShort peer_id, AdnlDbItem node,
|
||||
|
@ -99,12 +100,20 @@ class AdnlPeerTableImpl : public AdnlPeerTable {
|
|||
void create_ext_server(std::vector<AdnlNodeIdShort> ids, std::vector<td::uint16> ports,
|
||||
td::Promise<td::actor::ActorOwn<AdnlExtServer>> promise) override;
|
||||
|
||||
void create_tunnel(AdnlNodeIdShort dst, td::uint32 size,
|
||||
td::Promise<std::pair<td::actor::ActorOwn<AdnlTunnel>, AdnlAddress>> promise) override;
|
||||
|
||||
struct PrintId {};
|
||||
PrintId print_id() const {
|
||||
return PrintId{};
|
||||
}
|
||||
|
||||
private:
|
||||
struct LocalIdInfo {
|
||||
td::actor::ActorOwn<AdnlLocalId> local_id;
|
||||
td::uint8 cat;
|
||||
td::uint32 mode;
|
||||
};
|
||||
td::actor::ActorId<keyring::Keyring> keyring_;
|
||||
|
||||
td::actor::ActorId<AdnlNetworkManager> network_manager_;
|
||||
|
@ -114,13 +123,14 @@ class AdnlPeerTableImpl : public AdnlPeerTable {
|
|||
void deliver_one_message(AdnlNodeIdShort src, AdnlNodeIdShort dst, AdnlMessage message);
|
||||
|
||||
std::map<AdnlNodeIdShort, td::actor::ActorOwn<AdnlPeer>> peers_;
|
||||
std::map<AdnlNodeIdShort, std::pair<td::actor::ActorOwn<AdnlLocalId>, td::uint32>> local_ids_;
|
||||
std::map<AdnlChannelIdShort, td::actor::ActorId<AdnlChannel>> channels_;
|
||||
std::map<AdnlNodeIdShort, LocalIdInfo> local_ids_;
|
||||
std::map<AdnlChannelIdShort, std::pair<td::actor::ActorId<AdnlChannel>, td::uint8>> channels_;
|
||||
|
||||
td::actor::ActorOwn<AdnlDb> db_;
|
||||
|
||||
td::actor::ActorOwn<AdnlExtServer> ext_server_;
|
||||
|
||||
AdnlNodeIdShort proxy_addr_;
|
||||
//std::map<td::uint64, td::actor::ActorId<AdnlQuery>> out_queries_;
|
||||
//td::uint64 last_query_id_ = 1;
|
||||
};
|
||||
|
|
|
@ -482,7 +482,8 @@ void AdnlPeerPairImpl::create_channel(pubkeys::Ed25519 pub, td::uint32 date) {
|
|||
channel_ = R.move_as_ok();
|
||||
channel_inited_ = true;
|
||||
|
||||
td::actor::send_closure_later(peer_table_, &AdnlPeerTable::register_channel, channel_in_id_, channel_.get());
|
||||
td::actor::send_closure_later(peer_table_, &AdnlPeerTable::register_channel, channel_in_id_, local_id_,
|
||||
channel_.get());
|
||||
} else {
|
||||
VLOG(ADNL_WARNING) << this << ": failed to create channel: " << R.move_as_error();
|
||||
}
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with TON Blockchain Library. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
Copyright 2017-2019 Telegram Systems LLP
|
||||
Copyright 2017-2020 Telegram Systems LLP
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
exception statement from your version. If you delete this exception statement
|
||||
from all source files in the program, then also delete it here.
|
||||
|
||||
Copyright 2017-2019 Telegram Systems LLP
|
||||
Copyright 2017-2020 Telegram Systems LLP
|
||||
*/
|
||||
#include "td/actor/actor.h"
|
||||
#include "td/utils/buffer.h"
|
||||
|
@ -170,7 +170,10 @@ int main(int argc, char *argv[]) {
|
|||
|
||||
network_manager = ton::adnl::AdnlNetworkManager::create(static_cast<td::uint16>(addr.get_port()));
|
||||
|
||||
td::actor::send_closure(network_manager, &ton::adnl::AdnlNetworkManager::add_self_addr, addr, 0);
|
||||
ton::adnl::AdnlCategoryMask cat_mask;
|
||||
cat_mask[0] = true;
|
||||
td::actor::send_closure(network_manager, &ton::adnl::AdnlNetworkManager::add_self_addr, addr, std::move(cat_mask),
|
||||
0);
|
||||
|
||||
auto tladdr = ton::create_tl_object<ton::ton_api::adnl_address_udp>(addr.get_ipv4(), addr.get_port());
|
||||
auto addr_vec = std::vector<ton::tl_object_ptr<ton::ton_api::adnl_Address>>();
|
||||
|
@ -179,7 +182,8 @@ int main(int argc, char *argv[]) {
|
|||
std::move(addr_vec), ton::adnl::Adnl::adnl_start_time(), ton::adnl::Adnl::adnl_start_time(), 0, 2000000000);
|
||||
auto addrlist = ton::adnl::AdnlAddressList::create(tladdrlist).move_as_ok();
|
||||
|
||||
td::actor::send_closure(adnl, &ton::adnl::Adnl::add_id, ton::adnl::AdnlNodeIdFull{pub}, std::move(addrlist));
|
||||
td::actor::send_closure(adnl, &ton::adnl::Adnl::add_id, ton::adnl::AdnlNodeIdFull{pub}, std::move(addrlist),
|
||||
static_cast<td::uint8>(0));
|
||||
td::actor::send_closure(adnl, &ton::adnl::Adnl::subscribe, ton::adnl::AdnlNodeIdShort{pub.compute_short_id()},
|
||||
ton::adnl::Adnl::int_to_bytestring(ton::ton_api::adnl_ping::ID),
|
||||
std::make_unique<ton::adnl::Callback>());
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with TON Blockchain Library. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
Copyright 2017-2019 Telegram Systems LLP
|
||||
Copyright 2017-2020 Telegram Systems LLP
|
||||
*/
|
||||
#include "adnl-proxy-types.hpp"
|
||||
#include "tl-utils/tl-utils.hpp"
|
||||
|
@ -27,59 +27,84 @@ namespace ton {
|
|||
|
||||
namespace adnl {
|
||||
|
||||
td::Result<AdnlProxy::Packet> AdnlProxyNone::decrypt(td::BufferSlice packet) const {
|
||||
if (packet.size() < 32) {
|
||||
return td::Status::Error(ErrorCode::protoviolation, "bad signature");
|
||||
}
|
||||
if (packet.as_slice().truncate(32) != id_.as_slice()) {
|
||||
return td::Status::Error(ErrorCode::protoviolation, "bad proxy id");
|
||||
}
|
||||
Packet p{};
|
||||
p.flags = 0;
|
||||
p.ip = 0;
|
||||
p.port = 0;
|
||||
p.adnl_start_time = 0;
|
||||
p.seqno = 0;
|
||||
p.date = 0;
|
||||
p.data = std::move(packet);
|
||||
p.data.confirm_read(32);
|
||||
return std::move(p);
|
||||
}
|
||||
|
||||
td::BufferSlice AdnlProxyFast::encrypt(Packet packet) const {
|
||||
auto date = static_cast<td::uint32>(td::Clocks::system());
|
||||
auto signature = create_hash_tl_object<ton_api::adnl_proxyToFastHash>(
|
||||
packet.ip, packet.port, date, sha256_bits256(packet.data.as_slice()), shared_secret_);
|
||||
|
||||
auto obj = create_serialize_tl_object<ton_api::adnl_proxyToFast>(packet.ip, packet.port, date, signature);
|
||||
td::BufferSlice res{32 + obj.size() + packet.data.size()};
|
||||
auto S = res.as_slice();
|
||||
S.copy_from(td::Bits256::zero().as_slice());
|
||||
if (!packet.date) {
|
||||
packet.date = static_cast<td::int32>(td::Clocks::system());
|
||||
packet.flags |= 8;
|
||||
}
|
||||
auto obj = create_tl_object<ton_api::adnl_proxyPacketHeader>(id_, packet.flags, packet.ip, packet.port,
|
||||
packet.adnl_start_time, packet.seqno, packet.date,
|
||||
td::sha256_bits256(packet.data.as_slice()));
|
||||
char data[64];
|
||||
td::MutableSlice S{data, 64};
|
||||
S.copy_from(get_tl_object_sha256(obj).as_slice());
|
||||
S.remove_prefix(32);
|
||||
S.copy_from(obj.as_slice());
|
||||
S.remove_prefix(obj.size());
|
||||
S.copy_from(packet.data.as_slice());
|
||||
S.copy_from(shared_secret_.as_slice());
|
||||
|
||||
return res;
|
||||
obj->signature_ = td::sha256_bits256(td::Slice(data, 64));
|
||||
|
||||
return serialize_tl_object(obj, false, std::move(packet.data));
|
||||
}
|
||||
|
||||
td::Result<AdnlProxy::Packet> AdnlProxyFast::decrypt(td::BufferSlice packet) const {
|
||||
if (packet.size() < 36) {
|
||||
return td::Status::Error(ErrorCode::protoviolation, "too short packet");
|
||||
TRY_RESULT(obj, fetch_tl_prefix<ton_api::adnl_proxyPacketHeader>(packet, false));
|
||||
if (obj->proxy_id_ != id_) {
|
||||
return td::Status::Error(ErrorCode::protoviolation, "bad proxy id");
|
||||
}
|
||||
|
||||
td::Bits256 v;
|
||||
v.as_slice().copy_from(packet.as_slice().truncate(32));
|
||||
if (!v.is_zero()) {
|
||||
return td::Status::Error(ErrorCode::protoviolation, "non-zero DST");
|
||||
}
|
||||
packet.confirm_read(32);
|
||||
auto signature = std::move(obj->signature_);
|
||||
obj->signature_ = td::sha256_bits256(packet.as_slice());
|
||||
|
||||
TRY_RESULT(R, fetch_tl_prefix<ton_api::adnl_proxyToFast>(packet, true));
|
||||
char data[64];
|
||||
td::MutableSlice S{data, 64};
|
||||
S.copy_from(get_tl_object_sha256(obj).as_slice());
|
||||
S.remove_prefix(32);
|
||||
S.copy_from(shared_secret_.as_slice());
|
||||
|
||||
if (R->date_ < td::Clocks::system() - 8) {
|
||||
return td::Status::Error(ErrorCode::protoviolation, "too old date");
|
||||
}
|
||||
|
||||
auto signature = create_hash_tl_object<ton_api::adnl_proxyToFastHash>(
|
||||
R->ip_, R->port_, R->date_, sha256_bits256(packet.as_slice()), shared_secret_);
|
||||
if (signature != R->signature_) {
|
||||
if (td::sha256_bits256(td::Slice(data, 64)) != signature) {
|
||||
return td::Status::Error(ErrorCode::protoviolation, "bad signature");
|
||||
}
|
||||
|
||||
return Packet{static_cast<td::uint32>(R->ip_), static_cast<td::uint16>(R->port_), std::move(packet)};
|
||||
Packet p;
|
||||
p.flags = obj->flags_;
|
||||
p.ip = (p.flags & 1) ? obj->ip_ : 0;
|
||||
p.port = (p.flags & 1) ? static_cast<td::uint16>(obj->port_) : 0;
|
||||
p.adnl_start_time = (p.flags & 2) ? obj->adnl_start_time_ : 0;
|
||||
p.seqno = (p.flags & 4) ? obj->seqno_ : 0;
|
||||
p.date = (p.flags & 8) ? obj->date_ : 0;
|
||||
p.data = std::move(packet);
|
||||
|
||||
return std::move(p);
|
||||
}
|
||||
|
||||
td::Result<std::shared_ptr<AdnlProxy>> AdnlProxy::create(const ton_api::adnl_Proxy &proxy_type) {
|
||||
std::shared_ptr<AdnlProxy> R;
|
||||
ton_api::downcast_call(
|
||||
const_cast<ton_api::adnl_Proxy &>(proxy_type),
|
||||
td::overloaded([&](const ton_api::adnl_proxy_none &x) { R = std::make_shared<AdnlProxyNone>(); },
|
||||
td::overloaded([&](const ton_api::adnl_proxy_none &x) { R = std::make_shared<AdnlProxyNone>(x.id_); },
|
||||
[&](const ton_api::adnl_proxy_fast &x) {
|
||||
R = std::make_shared<AdnlProxyFast>(x.shared_secret_.as_slice());
|
||||
R = std::make_shared<AdnlProxyFast>(x.id_, x.shared_secret_.as_slice());
|
||||
}));
|
||||
return R;
|
||||
return std::move(R);
|
||||
}
|
||||
|
||||
} // namespace adnl
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with TON Blockchain Library. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
Copyright 2017-2019 Telegram Systems LLP
|
||||
Copyright 2017-2020 Telegram Systems LLP
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
|
@ -28,14 +28,19 @@ namespace adnl {
|
|||
class AdnlProxy {
|
||||
public:
|
||||
struct Packet {
|
||||
td::uint32 flags;
|
||||
td::uint32 ip;
|
||||
td::uint16 port;
|
||||
td::int32 adnl_start_time;
|
||||
td::int64 seqno;
|
||||
td::int32 date{0};
|
||||
td::BufferSlice data;
|
||||
};
|
||||
virtual ~AdnlProxy() = default;
|
||||
virtual td::BufferSlice encrypt(Packet packet) const = 0;
|
||||
virtual td::Result<Packet> decrypt(td::BufferSlice packet) const = 0;
|
||||
virtual tl_object_ptr<ton_api::adnl_Proxy> tl() const = 0;
|
||||
virtual const td::Bits256 &id() const = 0;
|
||||
|
||||
static td::Result<std::shared_ptr<AdnlProxy>> create(const ton_api::adnl_Proxy &proxy_type);
|
||||
};
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with TON Blockchain Library. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
Copyright 2017-2019 Telegram Systems LLP
|
||||
Copyright 2017-2020 Telegram Systems LLP
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
|
@ -28,31 +28,42 @@ namespace adnl {
|
|||
|
||||
class AdnlProxyNone : public AdnlProxy {
|
||||
public:
|
||||
AdnlProxyNone() {
|
||||
AdnlProxyNone(td::Bits256 id) : id_(id) {
|
||||
}
|
||||
td::BufferSlice encrypt(Packet packet) const override {
|
||||
return std::move(packet.data);
|
||||
}
|
||||
td::Result<Packet> decrypt(td::BufferSlice packet) const override {
|
||||
return Packet{0, 0, std::move(packet)};
|
||||
td::BufferSlice d{packet.data.size() + 32};
|
||||
d.as_slice().copy_from(id_.as_slice());
|
||||
d.as_slice().remove_prefix(32).copy_from(packet.data.as_slice());
|
||||
return d;
|
||||
}
|
||||
td::Result<Packet> decrypt(td::BufferSlice packet) const override;
|
||||
tl_object_ptr<ton_api::adnl_Proxy> tl() const override {
|
||||
return create_tl_object<ton_api::adnl_proxy_none>();
|
||||
return create_tl_object<ton_api::adnl_proxy_none>(id_);
|
||||
}
|
||||
const td::Bits256 &id() const override {
|
||||
return id_;
|
||||
}
|
||||
|
||||
private:
|
||||
td::Bits256 id_;
|
||||
};
|
||||
|
||||
class AdnlProxyFast : public AdnlProxy {
|
||||
public:
|
||||
AdnlProxyFast(td::Slice shared_secret)
|
||||
: shared_secret_(sha256_bits256(shared_secret)), shared_secret_raw_(shared_secret) {
|
||||
AdnlProxyFast(td::Bits256 id, td::Slice shared_secret)
|
||||
: id_(id), shared_secret_(sha256_bits256(shared_secret)), shared_secret_raw_(shared_secret) {
|
||||
}
|
||||
td::BufferSlice encrypt(Packet packet) const override;
|
||||
td::Result<Packet> decrypt(td::BufferSlice packet) const override;
|
||||
tl_object_ptr<ton_api::adnl_Proxy> tl() const override {
|
||||
return create_tl_object<ton_api::adnl_proxy_fast>(shared_secret_raw_.clone_as_buffer_slice());
|
||||
return create_tl_object<ton_api::adnl_proxy_fast>(id_, shared_secret_raw_.clone_as_buffer_slice());
|
||||
}
|
||||
const td::Bits256 &id() const override {
|
||||
return id_;
|
||||
}
|
||||
|
||||
private:
|
||||
td::Bits256 id_;
|
||||
td::Bits256 shared_secret_;
|
||||
td::SharedSlice shared_secret_raw_;
|
||||
};
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
exception statement from your version. If you delete this exception statement
|
||||
from all source files in the program, then also delete it here.
|
||||
|
||||
Copyright 2017-2019 Telegram Systems LLP
|
||||
Copyright 2017-2020 Telegram Systems LLP
|
||||
*/
|
||||
#include "td/actor/actor.h"
|
||||
#include "td/utils/buffer.h"
|
||||
|
@ -35,11 +35,13 @@
|
|||
#include "td/utils/port/path.h"
|
||||
#include "td/utils/port/user.h"
|
||||
#include "td/utils/filesystem.h"
|
||||
#include "td/utils/overloaded.h"
|
||||
#include "common/checksum.h"
|
||||
#include "common/errorcode.h"
|
||||
#include "tl-utils/tl-utils.hpp"
|
||||
#include "auto/tl/ton_api_json.h"
|
||||
#include "adnl-proxy-types.h"
|
||||
#include "adnl-received-mask.h"
|
||||
#include <map>
|
||||
|
||||
#if TD_DARWIN || TD_LINUX
|
||||
|
@ -50,12 +52,19 @@ namespace ton {
|
|||
|
||||
namespace adnl {
|
||||
|
||||
namespace {
|
||||
td::int32 start_time() {
|
||||
static td::int32 t = static_cast<td::int32>(td::Clocks::system());
|
||||
return t;
|
||||
}
|
||||
} // namespace
|
||||
|
||||
class Receiver : public td::actor::Actor {
|
||||
public:
|
||||
void start_up() override;
|
||||
void receive_common(td::BufferSlice data);
|
||||
void receive_from_client(td::BufferSlice data);
|
||||
void receive_to_client(td::BufferSlice data);
|
||||
void receive_common(td::IPAddress addr, td::BufferSlice data);
|
||||
void receive_from_client(td::IPAddress addr, td::BufferSlice data);
|
||||
void receive_to_client(td::IPAddress addr, td::BufferSlice data);
|
||||
|
||||
Receiver(td::uint16 in_port, td::uint16 out_port, std::shared_ptr<AdnlProxy> proxy, td::IPAddress client_addr)
|
||||
: in_port_(in_port), out_port_(out_port), proxy_(std::move(proxy)), addr_(client_addr) {
|
||||
|
@ -68,6 +77,10 @@ class Receiver : public td::actor::Actor {
|
|||
td::IPAddress addr_;
|
||||
td::actor::ActorOwn<td::UdpServer> out_udp_server_;
|
||||
td::actor::ActorOwn<td::UdpServer> in_udp_server_;
|
||||
|
||||
td::int32 client_start_time_{0};
|
||||
td::uint64 out_seqno_{0};
|
||||
AdnlReceivedMaskVersion received_;
|
||||
};
|
||||
|
||||
void Receiver::start_up() {
|
||||
|
@ -81,15 +94,18 @@ void Receiver::start_up() {
|
|||
const td::uint32 mode_;
|
||||
void on_udp_message(td::UdpMessage udp_message) override {
|
||||
if (udp_message.error.is_error()) {
|
||||
LOG(DEBUG) << udp_message.error;
|
||||
LOG(INFO) << "receifed udp message with error: " << udp_message.error;
|
||||
return;
|
||||
}
|
||||
if (mode_ == 0) {
|
||||
td::actor::send_closure_later(manager_, &Receiver::receive_common, std::move(udp_message.data));
|
||||
td::actor::send_closure_later(manager_, &Receiver::receive_common, udp_message.address,
|
||||
std::move(udp_message.data));
|
||||
} else if (mode_ == 1) {
|
||||
td::actor::send_closure_later(manager_, &Receiver::receive_from_client, std::move(udp_message.data));
|
||||
td::actor::send_closure_later(manager_, &Receiver::receive_from_client, udp_message.address,
|
||||
std::move(udp_message.data));
|
||||
} else {
|
||||
td::actor::send_closure_later(manager_, &Receiver::receive_to_client, std::move(udp_message.data));
|
||||
td::actor::send_closure_later(manager_, &Receiver::receive_to_client, udp_message.address,
|
||||
std::move(udp_message.data));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
@ -108,46 +124,152 @@ void Receiver::start_up() {
|
|||
}
|
||||
}
|
||||
|
||||
void Receiver::receive_common(td::BufferSlice data) {
|
||||
void Receiver::receive_common(td::IPAddress addr, td::BufferSlice data) {
|
||||
if (data.size() <= 32) {
|
||||
LOG(INFO) << "dropping too short packet: size=" << data.size();
|
||||
return;
|
||||
}
|
||||
|
||||
td::Bits256 id;
|
||||
id.as_slice().copy_from(data.as_slice().truncate(32));
|
||||
|
||||
if (id.is_zero()) {
|
||||
receive_from_client(std::move(data));
|
||||
if (proxy_->id().as_slice() == data.as_slice().truncate(32)) {
|
||||
receive_from_client(addr, std::move(data));
|
||||
} else {
|
||||
receive_to_client(std::move(data));
|
||||
receive_to_client(addr, std::move(data));
|
||||
}
|
||||
}
|
||||
|
||||
void Receiver::receive_from_client(td::BufferSlice data) {
|
||||
void Receiver::receive_from_client(td::IPAddress addr, td::BufferSlice data) {
|
||||
auto F = proxy_->decrypt(std::move(data));
|
||||
if (F.is_error()) {
|
||||
LOG(INFO) << "proxy: failed to decrypt message from client: " << F.move_as_error();
|
||||
return;
|
||||
}
|
||||
auto f = F.move_as_ok();
|
||||
if (f.flags & (1 << 16)) {
|
||||
LOG(INFO) << "proxy: dropping message from client: flag 16 is set";
|
||||
return;
|
||||
}
|
||||
|
||||
if (f.date) {
|
||||
if (f.date + 60.0 < td::Clocks::system() || f.date - 60.0 > td::Clocks::system()) {
|
||||
LOG(INFO) << "proxy: dropping message from client: date mismatch";
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if ((f.flags & 6) == 6) {
|
||||
if (received_.packet_is_delivered(f.adnl_start_time, f.seqno)) {
|
||||
LOG(INFO) << "proxy: dropping message from client: duplicate packet (or old seqno/start_time)";
|
||||
return;
|
||||
}
|
||||
received_.deliver_packet(f.adnl_start_time, f.seqno);
|
||||
}
|
||||
|
||||
if (f.flags & (1 << 17)) {
|
||||
auto F = fetch_tl_object<ton_api::adnl_ProxyControlPacket>(std::move(f.data), true);
|
||||
if (F.is_error()) {
|
||||
LOG(INFO) << this << ": dropping proxy packet: bad control packet: " << F.move_as_error();
|
||||
return;
|
||||
}
|
||||
ton_api::downcast_call(*F.move_as_ok().get(),
|
||||
td::overloaded(
|
||||
[&](const ton_api::adnl_proxyControlPacketPing &f) {
|
||||
auto data = create_serialize_tl_object<ton_api::adnl_proxyControlPacketPong>(f.id_);
|
||||
AdnlProxy::Packet p;
|
||||
p.flags = 6 | (1 << 16) | (1 << 17);
|
||||
if (addr.is_valid() && addr.is_ipv4()) {
|
||||
p.flags |= 1;
|
||||
p.ip = addr.get_ipv4();
|
||||
p.port = static_cast<td::uint16>(addr.get_port());
|
||||
} else {
|
||||
p.ip = 0;
|
||||
p.port = 0;
|
||||
}
|
||||
p.data = std::move(data);
|
||||
p.adnl_start_time = start_time();
|
||||
p.seqno = out_seqno_;
|
||||
p.data = std::move(data);
|
||||
|
||||
auto enc = proxy_->encrypt(std::move(p));
|
||||
|
||||
td::UdpMessage M;
|
||||
M.address = addr;
|
||||
M.data = std::move(enc);
|
||||
|
||||
td::actor::send_closure(
|
||||
in_udp_server_.empty() ? out_udp_server_.get() : in_udp_server_.get(),
|
||||
&td::UdpServer::send, std::move(M));
|
||||
},
|
||||
[&](const ton_api::adnl_proxyControlPacketPong &f) {},
|
||||
[&](const ton_api::adnl_proxyControlPacketRegister &f) {
|
||||
if (f.ip_ == 0 && f.port_ == 0) {
|
||||
if (addr.is_valid() && addr.is_ipv4()) {
|
||||
addr_ = addr;
|
||||
}
|
||||
} else {
|
||||
td::IPAddress a;
|
||||
auto S = a.init_host_port(td::IPAddress::ipv4_to_str(f.ip_), f.port_);
|
||||
if (S.is_ok()) {
|
||||
addr_ = a;
|
||||
} else {
|
||||
LOG(INFO) << "failed to init remote addr: " << S.move_as_error();
|
||||
}
|
||||
}
|
||||
}));
|
||||
return;
|
||||
}
|
||||
|
||||
if (!(f.flags & 1)) {
|
||||
LOG(INFO) << this << ": dropping proxy packet: no destination";
|
||||
return;
|
||||
}
|
||||
|
||||
td::IPAddress a;
|
||||
if (a.init_ipv4_port(td::IPAddress::ipv4_to_str(f.ip), f.port).is_error()) {
|
||||
LOG(INFO) << this << ": dropping proxy packet: invalid destination";
|
||||
return;
|
||||
}
|
||||
if (!a.is_valid()) {
|
||||
LOG(INFO) << this << ": dropping proxy packet: invalid destination";
|
||||
return;
|
||||
}
|
||||
|
||||
td::UdpMessage M;
|
||||
M.address = a;
|
||||
M.data = std::move(f.data);
|
||||
LOG(DEBUG) << this << ": proxying DOWN packet of length " << M.data.size() << " to " << a;
|
||||
|
||||
td::actor::send_closure(out_udp_server_.empty() ? in_udp_server_.get() : out_udp_server_.get(), &td::UdpServer::send,
|
||||
std::move(M));
|
||||
}
|
||||
|
||||
void Receiver::receive_to_client(td::BufferSlice data) {
|
||||
void Receiver::receive_to_client(td::IPAddress addr, td::BufferSlice data) {
|
||||
LOG(DEBUG) << "proxying to " << addr_;
|
||||
if (!addr_.is_valid() || !addr_.is_ipv4() || !addr_.get_ipv4()) {
|
||||
LOG(INFO) << this << ": dropping external packet: client not inited";
|
||||
return;
|
||||
}
|
||||
|
||||
AdnlProxy::Packet p;
|
||||
p.flags = (1 << 16);
|
||||
if (addr.is_valid() && addr.is_ipv4()) {
|
||||
p.flags |= 1;
|
||||
p.ip = addr.get_ipv4();
|
||||
p.port = static_cast<td::uint16>(addr.get_port());
|
||||
} else {
|
||||
p.ip = 0;
|
||||
p.port = 0;
|
||||
}
|
||||
p.flags |= 2;
|
||||
p.adnl_start_time = start_time();
|
||||
p.flags |= 4;
|
||||
p.seqno = ++out_seqno_;
|
||||
p.data = std::move(data);
|
||||
|
||||
LOG(DEBUG) << this << ": proxying UP packet of length " << p.data.size() << " to " << addr_;
|
||||
|
||||
td::UdpMessage M;
|
||||
M.address = addr_;
|
||||
M.data = std::move(data);
|
||||
M.data = proxy_->encrypt(std::move(p));
|
||||
|
||||
td::actor::send_closure(in_udp_server_.empty() ? out_udp_server_.get() : in_udp_server_.get(), &td::UdpServer::send,
|
||||
std::move(M));
|
||||
|
@ -204,7 +326,7 @@ int main(int argc, char *argv[]) {
|
|||
});
|
||||
p.add_option('l', "logname", "log to file", [&](td::Slice fname) {
|
||||
auto F = std::make_unique<td::FileLog>();
|
||||
TRY_STATUS(F->init(fname.str(), std::numeric_limits<td::uint64>::max(), true));
|
||||
TRY_STATUS(F->init(fname.str(), std::numeric_limits<td::int64>::max(), true));
|
||||
logger_ = std::move(F);
|
||||
td::log_interface = logger_.get();
|
||||
return td::Status::OK();
|
||||
|
@ -248,7 +370,9 @@ int main(int argc, char *argv[]) {
|
|||
}
|
||||
TRY_RESULT(proxy, ton::adnl::AdnlProxy::create(*y->proxy_type_.get()));
|
||||
td::IPAddress a;
|
||||
a.init_ipv4_port(td::IPAddress::ipv4_to_str(y->dst_ip_), static_cast<td::uint16>(y->dst_port_)).ensure();
|
||||
if (y->dst_ip_ || y->dst_port_) {
|
||||
a.init_ipv4_port(td::IPAddress::ipv4_to_str(y->dst_ip_), static_cast<td::uint16>(y->dst_port_)).ensure();
|
||||
}
|
||||
|
||||
scheduler.run_in_context([&] {
|
||||
x.push_back(td::actor::create_actor<ton::adnl::Receiver>("adnl-proxy", in_port, out_port, std::move(proxy), a));
|
||||
|
|
84
adnl/adnl-received-mask.h
Normal file
84
adnl/adnl-received-mask.h
Normal file
|
@ -0,0 +1,84 @@
|
|||
#pragma once
|
||||
|
||||
#include "td/utils/int_types.h"
|
||||
#include "td/utils/logging.h"
|
||||
|
||||
namespace ton {
|
||||
|
||||
namespace adnl {
|
||||
|
||||
class AdnlReceivedMask {
|
||||
public:
|
||||
void reset() {
|
||||
seqno_ = 0;
|
||||
mask_ = 0;
|
||||
}
|
||||
bool packet_is_delivered(td::int64 seqno) const {
|
||||
if (seqno <= 0) {
|
||||
return false;
|
||||
}
|
||||
if (seqno + 64 <= seqno_) {
|
||||
return true;
|
||||
}
|
||||
if (seqno > seqno_) {
|
||||
return false;
|
||||
}
|
||||
return mask_ & (1ull << (seqno_ - seqno));
|
||||
}
|
||||
void deliver_packet(td::int64 seqno) {
|
||||
CHECK(!packet_is_delivered(seqno));
|
||||
|
||||
CHECK(seqno > 0);
|
||||
if (seqno <= seqno_) {
|
||||
mask_ |= (1ull << (seqno_ - seqno));
|
||||
} else {
|
||||
auto old = seqno_;
|
||||
seqno_ = seqno;
|
||||
if (seqno_ - old >= 64) {
|
||||
mask_ = 1;
|
||||
} else {
|
||||
mask_ = mask_ << (seqno_ - old);
|
||||
mask_ |= 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
td::int64 seqno_{0};
|
||||
td::uint64 mask_{0};
|
||||
};
|
||||
|
||||
class AdnlReceivedMaskVersion {
|
||||
public:
|
||||
bool packet_is_delivered(td::int32 utime, td::uint64 seqno) {
|
||||
if (utime < utime_) {
|
||||
return true;
|
||||
} else if (utime == utime_) {
|
||||
return mask_.packet_is_delivered(seqno);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
void deliver_packet(td::int32 utime, td::uint64 seqno) {
|
||||
CHECK(utime >= utime_);
|
||||
if (utime == utime_) {
|
||||
mask_.deliver_packet(seqno);
|
||||
} else {
|
||||
utime_ = utime;
|
||||
mask_.reset();
|
||||
mask_.deliver_packet(seqno);
|
||||
}
|
||||
}
|
||||
void reset() {
|
||||
mask_.reset();
|
||||
utime_ = 0;
|
||||
}
|
||||
|
||||
private:
|
||||
AdnlReceivedMask mask_;
|
||||
td::int32 utime_{0};
|
||||
};
|
||||
|
||||
} // namespace adnl
|
||||
|
||||
} // namespace ton
|
|
@ -14,7 +14,7 @@
|
|||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with TON Blockchain Library. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
Copyright 2017-2019 Telegram Systems LLP
|
||||
Copyright 2017-2020 Telegram Systems LLP
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
|
@ -34,9 +34,10 @@ class TestLoopbackNetworkManager : public ton::adnl::AdnlNetworkManager {
|
|||
callback_ = std::move(callback);
|
||||
}
|
||||
|
||||
void add_self_addr(td::IPAddress addr, td::uint32 priority) override {
|
||||
void add_self_addr(td::IPAddress addr, AdnlCategoryMask cat_mask, td::uint32 priority) override {
|
||||
}
|
||||
void add_proxy_addr(td::IPAddress addr, std::shared_ptr<AdnlProxy> proxy, td::uint32 priority) override {
|
||||
void add_proxy_addr(td::IPAddress addr, td::uint16 local_port, std::shared_ptr<AdnlProxy> proxy,
|
||||
AdnlCategoryMask cat_mask, td::uint32 priority) override {
|
||||
}
|
||||
void send_udp_packet(ton::adnl::AdnlNodeIdShort src_id, ton::adnl::AdnlNodeIdShort dst_id, td::IPAddress dst_addr,
|
||||
td::uint32 priority, td::BufferSlice data) override {
|
||||
|
@ -48,7 +49,9 @@ class TestLoopbackNetworkManager : public ton::adnl::AdnlNetworkManager {
|
|||
return;
|
||||
}
|
||||
CHECK(callback_);
|
||||
callback_->receive_packet(dst_addr, std::move(data));
|
||||
AdnlCategoryMask m;
|
||||
m[0] = true;
|
||||
callback_->receive_packet(dst_addr, std::move(m), std::move(data));
|
||||
}
|
||||
|
||||
void add_node_id(AdnlNodeIdShort id, bool allow_send, bool allow_receive) {
|
||||
|
@ -68,6 +71,8 @@ class TestLoopbackNetworkManager : public ton::adnl::AdnlNetworkManager {
|
|||
CHECK(p >= 0 && p <= 1);
|
||||
loss_probability_ = p;
|
||||
}
|
||||
void set_local_id_category(AdnlNodeIdShort id, td::uint8 cat) override {
|
||||
}
|
||||
|
||||
TestLoopbackNetworkManager() {
|
||||
}
|
||||
|
|
97
adnl/adnl-tunnel.cpp
Normal file
97
adnl/adnl-tunnel.cpp
Normal file
|
@ -0,0 +1,97 @@
|
|||
#include "adnl-tunnel.h"
|
||||
#include "adnl-peer-table.h"
|
||||
|
||||
namespace ton {
|
||||
|
||||
namespace adnl {
|
||||
|
||||
void AdnlInboundTunnelEndpoint::receive_packet(AdnlNodeIdShort src, td::IPAddress src_addr, td::BufferSlice datagram) {
|
||||
receive_packet_cont(src, src_addr, std::move(datagram), 0);
|
||||
}
|
||||
|
||||
void AdnlInboundTunnelEndpoint::receive_packet_cont(AdnlNodeIdShort src, td::IPAddress src_addr,
|
||||
td::BufferSlice datagram, size_t idx) {
|
||||
if (datagram.size() <= 32) {
|
||||
VLOG(ADNL_INFO) << "dropping too short datagram";
|
||||
return;
|
||||
}
|
||||
if (datagram.as_slice().truncate(32) != decrypt_via_[idx].as_slice()) {
|
||||
VLOG(ADNL_INFO) << "invalid tunnel midpoint";
|
||||
return;
|
||||
}
|
||||
datagram.confirm_read(32);
|
||||
|
||||
auto P = td::PromiseCreator::lambda([SelfId = actor_id(this), src, src_addr, idx](td::Result<td::BufferSlice> R) {
|
||||
if (R.is_error()) {
|
||||
VLOG(ADNL_INFO) << "dropping tunnel packet: failed to decrypt: " << R.move_as_error();
|
||||
return;
|
||||
} else {
|
||||
td::actor::send_closure(SelfId, &AdnlInboundTunnelEndpoint::decrypted_packet, src, src_addr, R.move_as_ok(), idx);
|
||||
}
|
||||
});
|
||||
td::actor::send_closure(keyring_, &keyring::Keyring::decrypt_message, decrypt_via_[idx], std::move(datagram),
|
||||
std::move(P));
|
||||
}
|
||||
|
||||
void AdnlInboundTunnelEndpoint::decrypted_packet(AdnlNodeIdShort src, td::IPAddress src_addr, td::BufferSlice data,
|
||||
size_t idx) {
|
||||
if (idx == decrypt_via_.size() - 1) {
|
||||
td::actor::send_closure(adnl_, &AdnlPeerTable::receive_packet, src_addr, std::move(data));
|
||||
return;
|
||||
}
|
||||
auto F = fetch_tl_object<ton_api::adnl_tunnelPacketContents>(std::move(data), true);
|
||||
if (F.is_error()) {
|
||||
VLOG(ADNL_INFO) << "dropping tunnel packet: failed to fetch: " << F.move_as_error();
|
||||
return;
|
||||
}
|
||||
auto packet = F.move_as_ok();
|
||||
|
||||
td::IPAddress addr;
|
||||
if (packet->flags_ & 1) {
|
||||
addr.init_host_port(td::IPAddress::ipv4_to_str(packet->from_ip_), packet->from_port_).ignore();
|
||||
}
|
||||
|
||||
if (packet->flags_ & 2) {
|
||||
receive_packet_cont(src, addr, std::move(packet->message_), idx + 1);
|
||||
}
|
||||
}
|
||||
|
||||
void AdnlInboundTunnelMidpoint::start_up() {
|
||||
encrypt_key_hash_ = encrypt_via_.compute_short_id();
|
||||
auto R = encrypt_via_.create_encryptor();
|
||||
if (R.is_error()) {
|
||||
return;
|
||||
}
|
||||
encryptor_ = R.move_as_ok();
|
||||
}
|
||||
|
||||
void AdnlInboundTunnelMidpoint::receive_packet(AdnlNodeIdShort src, td::IPAddress src_addr, td::BufferSlice datagram) {
|
||||
if (!encryptor_) {
|
||||
return;
|
||||
}
|
||||
auto obj = create_tl_object<ton_api::adnl_tunnelPacketContents>();
|
||||
obj->flags_ = 2;
|
||||
obj->message_ = std::move(datagram);
|
||||
if (src_addr.is_valid() && src_addr.is_ipv4()) {
|
||||
obj->flags_ |= 1;
|
||||
obj->from_ip_ = src_addr.get_ipv4();
|
||||
obj->from_port_ = src_addr.get_port();
|
||||
}
|
||||
auto packet = serialize_tl_object(std::move(obj), true);
|
||||
auto dataR = encryptor_->encrypt(packet.as_slice());
|
||||
if (dataR.is_error()) {
|
||||
return;
|
||||
}
|
||||
auto data = dataR.move_as_ok();
|
||||
td::BufferSlice enc{data.size() + 32};
|
||||
auto S = enc.as_slice();
|
||||
S.copy_from(encrypt_key_hash_.as_slice());
|
||||
S.remove_prefix(32);
|
||||
S.copy_from(data.as_slice());
|
||||
|
||||
td::actor::send_closure(adnl_, &Adnl::send_message_ex, proxy_as_, proxy_to_, std::move(enc),
|
||||
Adnl::SendFlags::direct_only);
|
||||
}
|
||||
|
||||
} // namespace adnl
|
||||
} // namespace ton
|
73
adnl/adnl-tunnel.h
Normal file
73
adnl/adnl-tunnel.h
Normal file
|
@ -0,0 +1,73 @@
|
|||
#pragma once
|
||||
|
||||
#include "adnl.h"
|
||||
#include "adnl-peer-table.h"
|
||||
#include "keys/encryptor.h"
|
||||
|
||||
#include <map>
|
||||
|
||||
namespace ton {
|
||||
|
||||
namespace adnl {
|
||||
|
||||
class AdnlInboundTunnelPoint : public AdnlTunnel {
|
||||
public:
|
||||
virtual ~AdnlInboundTunnelPoint() = default;
|
||||
virtual void receive_packet(AdnlNodeIdShort src, td::IPAddress src_addr, td::BufferSlice datagram) = 0;
|
||||
};
|
||||
|
||||
class AdnlInboundTunnelEndpoint : public AdnlInboundTunnelPoint {
|
||||
public:
|
||||
AdnlInboundTunnelEndpoint(PublicKeyHash pubkey_hash, std::vector<PublicKeyHash> decrypt_via, AdnlNodeIdShort proxy_to,
|
||||
td::actor::ActorId<keyring::Keyring> keyring, td::actor::ActorId<AdnlPeerTable> adnl)
|
||||
: pubkey_hash_(std::move(pubkey_hash))
|
||||
, decrypt_via_(std::move(decrypt_via))
|
||||
, proxy_to_(std::move(proxy_to))
|
||||
, keyring_(std::move(keyring))
|
||||
, adnl_(std::move(adnl)) {
|
||||
}
|
||||
|
||||
void receive_packet(AdnlNodeIdShort src, td::IPAddress src_addr, td::BufferSlice datagram) override;
|
||||
void receive_packet_cont(AdnlNodeIdShort src, td::IPAddress src_addr, td::BufferSlice datagram, size_t idx);
|
||||
void decrypted_packet(AdnlNodeIdShort src, td::IPAddress src_addr, td::BufferSlice data, size_t idx);
|
||||
|
||||
private:
|
||||
PublicKeyHash pubkey_hash_;
|
||||
std::vector<PublicKeyHash> decrypt_via_;
|
||||
AdnlNodeIdShort proxy_to_;
|
||||
td::actor::ActorId<keyring::Keyring> keyring_;
|
||||
td::actor::ActorId<AdnlPeerTable> adnl_;
|
||||
};
|
||||
|
||||
class AdnlInboundTunnelMidpoint : public AdnlInboundTunnelPoint {
|
||||
public:
|
||||
AdnlInboundTunnelMidpoint(ton::PublicKey encrypt_via, AdnlNodeIdShort proxy_to, AdnlNodeIdShort proxy_as,
|
||||
td::actor::ActorId<keyring::Keyring> keyring, td::actor::ActorId<AdnlPeerTable> adnl)
|
||||
: encrypt_via_(std::move(encrypt_via)), proxy_to_(proxy_to), proxy_as_(proxy_as), keyring_(keyring), adnl_(adnl) {
|
||||
}
|
||||
void start_up() override;
|
||||
void receive_packet(AdnlNodeIdShort src, td::IPAddress src_addr, td::BufferSlice datagram) override;
|
||||
|
||||
private:
|
||||
ton::PublicKeyHash encrypt_key_hash_;
|
||||
ton::PublicKey encrypt_via_;
|
||||
std::unique_ptr<Encryptor> encryptor_;
|
||||
AdnlNodeIdShort proxy_to_;
|
||||
AdnlNodeIdShort proxy_as_;
|
||||
td::actor::ActorId<keyring::Keyring> keyring_;
|
||||
td::actor::ActorId<AdnlPeerTable> adnl_;
|
||||
};
|
||||
|
||||
class AdnlProxyNode : public td::actor::Actor {
|
||||
public:
|
||||
void receive_message(AdnlNodeIdShort src, AdnlNodeIdShort dst, td::BufferSlice data);
|
||||
void receive_query(AdnlNodeIdShort src, AdnlNodeIdShort dst, td::BufferSlice data,
|
||||
td::Promise<td::BufferSlice> promise);
|
||||
|
||||
private:
|
||||
std::map<PublicKeyHash, td::actor::ActorOwn<AdnlInboundTunnelMidpoint>> mid_;
|
||||
};
|
||||
|
||||
} // namespace adnl
|
||||
|
||||
} // namespace ton
|
12
adnl/adnl.h
12
adnl/adnl.h
|
@ -14,7 +14,7 @@
|
|||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with TON Blockchain Library. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
Copyright 2017-2019 Telegram Systems LLP
|
||||
Copyright 2017-2020 Telegram Systems LLP
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
|
@ -58,6 +58,8 @@ class AdnlSenderInterface : public td::actor::Actor {
|
|||
td::uint64 max_answer_size) = 0;
|
||||
};
|
||||
|
||||
class AdnlTunnel : public td::actor::Actor {};
|
||||
|
||||
class Adnl : public AdnlSenderInterface {
|
||||
public:
|
||||
class Callback {
|
||||
|
@ -88,10 +90,10 @@ class Adnl : public AdnlSenderInterface {
|
|||
virtual void add_static_nodes_from_config(AdnlNodesList nodes) = 0;
|
||||
|
||||
// adds local id. After that you can send/receive messages from/to this id
|
||||
void add_id(AdnlNodeIdFull id, AdnlAddressList addr_list) {
|
||||
add_id_ex(std::move(id), std::move(addr_list), 0);
|
||||
void add_id(AdnlNodeIdFull id, AdnlAddressList addr_list, td::uint8 cat) {
|
||||
add_id_ex(std::move(id), std::move(addr_list), cat, 0);
|
||||
}
|
||||
virtual void add_id_ex(AdnlNodeIdFull id, AdnlAddressList addr_list, td::uint32 mode) = 0;
|
||||
virtual void add_id_ex(AdnlNodeIdFull id, AdnlAddressList addr_list, td::uint8 cat, td::uint32 mode) = 0;
|
||||
virtual void del_id(AdnlNodeIdShort id, td::Promise<td::Unit> promise) = 0;
|
||||
|
||||
// subscribe to (some) messages(+queries) to this local id
|
||||
|
@ -113,6 +115,8 @@ class Adnl : public AdnlSenderInterface {
|
|||
|
||||
virtual void create_ext_server(std::vector<AdnlNodeIdShort> ids, std::vector<td::uint16> ports,
|
||||
td::Promise<td::actor::ActorOwn<AdnlExtServer>> promise) = 0;
|
||||
virtual void create_tunnel(AdnlNodeIdShort dst, td::uint32 size,
|
||||
td::Promise<std::pair<td::actor::ActorOwn<AdnlTunnel>, AdnlAddress>> promise) = 0;
|
||||
|
||||
static td::actor::ActorOwn<Adnl> create(std::string db, td::actor::ActorId<keyring::Keyring> keyring);
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue