From 4737d5f83dbe8ed685f0a202fa31d77c68d71cd0 Mon Sep 17 00:00:00 2001 From: Oleg Baranov Date: Wed, 19 Feb 2025 17:18:40 +0400 Subject: [PATCH 01/13] ADNL Tunnel library integration --- .gitignore | 1 + CMakeLists.txt | 14 +++ adnl/adnl-network-manager.cpp | 46 ++++++++++ adnl/adnl-network-manager.h | 2 + adnl/adnl-network-manager.hpp | 7 ++ tdnet/CMakeLists.txt | 2 +- tdnet/td/net/UdpServer.cpp | 121 ++++++++++++++++++++++++++ tdnet/td/net/UdpServer.h | 4 + tdnet/td/net/tunnel/libtunnel.h | 104 ++++++++++++++++++++++ tl/generate/scheme/ton_api.tl | 2 +- tl/generate/scheme/ton_api.tlo | Bin 102484 -> 102524 bytes validator-engine/validator-engine.cpp | 53 +++++++++-- validator-engine/validator-engine.hpp | 2 + 13 files changed, 348 insertions(+), 10 deletions(-) create mode 100644 tdnet/td/net/tunnel/libtunnel.h diff --git a/.gitignore b/.gitignore index e5bb366c..be21fd00 100644 --- a/.gitignore +++ b/.gitignore @@ -24,3 +24,4 @@ libsodium-1.0.18-stable-msvc.zip libmicrohttpd-0.9.77-w32-bin.zip openssl-3.1.4.zip readline-5.0-1-lib.zip +libtunnel.a \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt index cea3fc7e..f3d34b86 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -105,6 +105,20 @@ option(TON_USE_ASAN "Use \"ON\" to enable AddressSanitizer." OFF) option(TON_USE_TSAN "Use \"ON\" to enable ThreadSanitizer." OFF) option(TON_USE_UBSAN "Use \"ON\" to enable UndefinedBehaviorSanitizer." OFF) set(TON_ARCH "native" CACHE STRING "Architecture, will be passed to -march=") +option(TON_USE_GO_TUNNEL "Use \"ON\" to enable ADNL Tunnel over shared Go library." ON) + +if (TON_USE_GO_TUNNEL) + set(TUNNEL_GO_LIB_PATH "${CMAKE_CURRENT_SOURCE_DIR}/libtunnel.a") + if (EXISTS "${TUNNEL_GO_LIB_PATH}") + message(STATUS "Found ADNL Tunnel library (Go): ${TUNNEL_GO_LIB_PATH}") + + add_library(tunnel STATIC IMPORTED) + set_target_properties(tunnel PROPERTIES IMPORTED_LOCATION "${TUNNEL_GO_LIB_PATH}") + set(TUNNEL_LIB_IF_USED "tunnel") + else() + message(FATAL_ERROR "Missing ADNL Tunnel library (Go), but enabled: ${TUNNEL_GO_LIB_PATH}") + endif() +endif() #BEGIN M1 support EXECUTE_PROCESS( COMMAND uname -m COMMAND tr -d '\n' OUTPUT_VARIABLE ARCHITECTURE ) diff --git a/adnl/adnl-network-manager.cpp b/adnl/adnl-network-manager.cpp index 077fb939..ba5d9208 100644 --- a/adnl/adnl-network-manager.cpp +++ b/adnl/adnl-network-manager.cpp @@ -76,6 +76,35 @@ size_t AdnlNetworkManagerImpl::add_listening_udp_port(td::uint16 port) { return idx; } +size_t AdnlNetworkManagerImpl::add_tunnel_udp_port(td::uint16 port, td::Promise on_ready) { + 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 manager, size_t idx) + : manager_(std::move(manager)), idx_(idx) { + } + + private: + td::actor::ActorShared 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), + idx_); + } + }; + + auto idx = udp_sockets_.size(); + auto X = td::UdpServer::create_via_tunnel("udp tunnel server", port, + std::make_unique(actor_shared(this), idx), std::move(on_ready)); + X.ensure(); + port_2_socket_[port] = idx; + udp_sockets_.push_back(UdpSocketDesc{port, X.move_as_ok()}); + return idx; +} + void AdnlNetworkManagerImpl::add_self_addr(td::IPAddress addr, AdnlCategoryMask cat_mask, td::uint32 priority) { auto port = td::narrow_cast(addr.get_port()); size_t idx = add_listening_udp_port(port); @@ -92,6 +121,23 @@ void AdnlNetworkManagerImpl::add_self_addr(td::IPAddress addr, AdnlCategoryMask out_desc_[priority].push_back(std::move(d)); } +void AdnlNetworkManagerImpl::add_tunnel(td::uint16 port, AdnlCategoryMask cat_mask, td::uint32 priority, + td::Promise on_ready) { + size_t idx = add_tunnel_udp_port(port, std::move(on_ready)); + + 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 proxy, AdnlCategoryMask cat_mask, td::uint32 priority) { size_t idx = add_listening_udp_port(local_port); diff --git a/adnl/adnl-network-manager.h b/adnl/adnl-network-manager.h index 67cf602a..6d439a12 100644 --- a/adnl/adnl-network-manager.h +++ b/adnl/adnl-network-manager.h @@ -70,6 +70,8 @@ class AdnlNetworkManager : public td::actor::Actor { virtual void install_callback(std::unique_ptr callback) = 0; + virtual void add_tunnel(td::uint16 port, AdnlCategoryMask cat_mask, td::uint32 priority, + td::Promise on_ready) = 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 proxy, AdnlCategoryMask cat_mask, td::uint32 priority) = 0; diff --git a/adnl/adnl-network-manager.hpp b/adnl/adnl-network-manager.hpp index a77be19d..30a9efc8 100644 --- a/adnl/adnl-network-manager.hpp +++ b/adnl/adnl-network-manager.hpp @@ -95,6 +95,10 @@ class AdnlNetworkManagerImpl : public AdnlNetworkManager { size_t in_desc{std::numeric_limits::max()}; bool allow_proxy{false}; }; + struct TunnelDesc { + size_t index{}; + td::IPAddress address; + }; OutDesc *choose_out_iface(td::uint8 cat, td::uint32 priority); @@ -127,6 +131,8 @@ class AdnlNetworkManagerImpl : public AdnlNetworkManager { in_desc_.push_back(std::move(desc)); } + void add_tunnel(td::uint16 port, AdnlCategoryMask cat_mask, td::uint32 priority, + td::Promise on_ready) override; 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 proxy, AdnlCategoryMask cat_mask, td::uint32 priority) override; @@ -141,6 +147,7 @@ class AdnlNetworkManagerImpl : public AdnlNetworkManager { } } + size_t add_tunnel_udp_port(td::uint16 port, td::Promise on_ready); size_t add_listening_udp_port(td::uint16 port); void receive_udp_message(td::UdpMessage message, size_t idx); void proxy_register(OutDesc &desc); diff --git a/tdnet/CMakeLists.txt b/tdnet/CMakeLists.txt index bc00a676..ae056099 100644 --- a/tdnet/CMakeLists.txt +++ b/tdnet/CMakeLists.txt @@ -12,7 +12,7 @@ set(TDNET_SOURCE add_library(tdnet STATIC ${TDNET_SOURCE}) target_include_directories(tdnet PUBLIC $) -target_link_libraries(tdnet PUBLIC tdactor) +target_link_libraries(tdnet PUBLIC tdactor ${TUNNEL_LIB_IF_USED}) add_executable(tcp_ping_pong example/tcp_ping_pong.cpp) target_link_libraries(tcp_ping_pong PRIVATE tdactor tdnet) diff --git a/tdnet/td/net/UdpServer.cpp b/tdnet/td/net/UdpServer.cpp index ba28c5cf..4e3e8ff5 100644 --- a/tdnet/td/net/UdpServer.cpp +++ b/tdnet/td/net/UdpServer.cpp @@ -20,6 +20,8 @@ #include "td/net/FdListener.h" #include "td/net/TcpListener.h" +#include "td/net/tunnel/libtunnel.h" + #include "td/utils/BufferedFd.h" #include @@ -29,6 +31,118 @@ namespace { int VERBOSITY_NAME(udp_server) = VERBOSITY_NAME(DEBUG) + 10; } namespace detail { + +class UdpServerTunnelImpl : public UdpServer { + public: + void start_up() override; + void alarm() override; + + void send(td::UdpMessage &&message) override; + static td::actor::ActorOwn create(td::Slice name, int32 port, std::unique_ptr callback, + td::Promise on_ready); + + UdpServerTunnelImpl(int32 port, std::unique_ptr callback, td::Promise on_ready); + +private: + td::Promise on_ready_; + char out_buf_[(16+2+1500)*300]; + size_t out_buf_offset_ = 0; + size_t out_buf_msg_num_ = 0; + size_t tunnel_index_; + double last_batch_at_ = Time::now(); + + int32 port_; + std::unique_ptr callback_; + + static void on_recv_batch(void *next, char *data, size_t num); + +}; + +void UdpServerTunnelImpl::send(td::UdpMessage &&message) { + auto sock = message.address.get_sockaddr(); + auto sz = message.data.size(); + + // ip+port + memcpy(out_buf_ + out_buf_offset_, sock, sizeof(sockaddr)); + out_buf_offset_ += sizeof(sockaddr); + + // data len (2 bytes) + out_buf_[out_buf_offset_] = static_cast(sz >> 8); + out_buf_[out_buf_offset_ + 1] = static_cast(sz & 0xff); + + memcpy(out_buf_ + out_buf_offset_ + 2, message.data.data(), sz); + out_buf_offset_ += 2 + sz; + out_buf_msg_num_++; + + + if (out_buf_msg_num_ >= 100) { + td::Timer timer; + WriteTunnel(tunnel_index_, out_buf_, out_buf_msg_num_); + LOG(INFO) << "Sending messages " << out_buf_msg_num_ << " | " << timer.elapsed(); + + out_buf_offset_ = 0; + out_buf_msg_num_ = 0; + last_batch_at_ = Time::now(); + } + // LOG(INFO) << "TUN message to: "; +} + +void UdpServerTunnelImpl::alarm() { + auto now = Time::now(); + if (out_buf_msg_num_ > 0 && now-last_batch_at_ > 0.02) { + td::Timer timer; + WriteTunnel(tunnel_index_, out_buf_, out_buf_msg_num_); + LOG(ERROR) << "Sending messages from alarm " << out_buf_msg_num_ << " | " << timer.elapsed(); + + out_buf_offset_ = 0; + out_buf_msg_num_ = 0; + last_batch_at_ = now; + } + + alarm_timestamp() = td::Timestamp::in(0.05); +} + +void UdpServerTunnelImpl::start_up() { + auto cfg = Slice("{\n\t\t\"TunnelServerKey\": \"2Kg9YuGSbpPA8+2UlMyef47UOzFt7fFjz9QREGUhP0U=\",\n\t\t\"TunnelThreads\": 10,\n\t\t\"PaymentsEnabled\": false,\n\t\t\"Payments\": {\n\t\t\t\"PaymentsServerKey\": \"8BfanhwJYWRlASVw6mXeuUxoMyB73CDfHYLQ8mF5FxE=\",\n\t\t\t\"WalletPrivateKey\": \"8BfanhwJYWRlASVw6mXeuUxoMyB73CDfHYLQ8mF5FxA=\",\n\t\t\t\"PaymentsListenAddr\": \"0.0.0.0:13131\",\n\t\t\t\"DBPath\": \"./payments-db/\",\n\t\t\t\"SecureProofPolicy\": false,\n\t\t\t\"ChannelConfig\": {\n\t\t\t\t\"VirtualChannelProxyFee\": \"0.01\",\n\t\t\t\t\"QuarantineDurationSec\": 600,\n\t\t\t\t\"MisbehaviorFine\": \"0.15\",\n\t\t\t\t\"ConditionalCloseDurationSec\": 180\n\t\t\t}\n\t\t},\n\t\t\"OutGateway\": {\n\t\t\t\"Key\": \"cKrWi/IgAKvd3Ro92ap2IfKABX3C4rQI59P+v1g+vOg=\",\n\t\t\t\"Payment\": null},\n\t\t\"RouteOut\": [],\n\t\t\"RouteIn\": []\n\t}"); + auto netCfg = Slice("{\n\t\"liteservers\": [\n\t\t{\n\t\t\t\"ip\": 822907680,\n\t\t\t\"port\": 27842,\n\t\t\t\"provided\":\"Beavis\",\n\t\t\t\"id\": {\n\t\t\t\t\"@type\": \"pub.ed25519\",\n\t\t\t\t\"key\": \"sU7QavX2F964iI9oToP9gffQpCQIoOLppeqL/pdPvpM=\"\n\t\t\t}\n\t\t},\n\t\t{\n\t\t\t\"ip\": -1468571697,\n\t\t\t\"port\": 27787,\n\t\t\t\"provided\":\"Beavis\",\n\t\t\t\"id\": {\n\t\t\t\t\"@type\": \"pub.ed25519\",\n\t\t\t\t\"key\": \"Y/QVf6G5VDiKTZOKitbFVm067WsuocTN8Vg036A4zGk=\"\n\t\t\t}\n\t\t},\n\t\t{\n\t\t\t\"ip\": -1468575011,\n\t\t\t\"port\": 51088,\n\t\t\t\"provided\":\"Beavis\",\n\t\t\t\"id\": {\n\t\t\t\t\"@type\": \"pub.ed25519\",\n\t\t\t\t\"key\": \"Sy5ghr3EahQd/1rDayzZXt5+inlfF+7kLfkZDJcU/ek=\"\n\t\t\t}\n\t\t},\n\t\t{\n\t\t\t\"ip\": 1844203537,\n\t\t\t\"port\": 37537,\n\t\t\t\"provided\":\"Neo\",\n\t\t\t\"id\": {\n\t\t\t\t\"@type\": \"pub.ed25519\",\n\t\t\t\t\"key\": \"K1F7zEe0ETf+SwkefLS56hJE8x42sjCVsBJJuaY7nEA=\"\n\t\t\t}\n\t\t},\n\t\t{\n\t\t\t\"ip\": 1844203589,\n\t\t\t\"port\": 34411,\n\t\t\t\"provided\":\"Neo\",\n\t\t\t\"id\": {\n\t\t\t\t\"@type\": \"pub.ed25519\",\n\t\t\t\t\"key\": \"pOpRRpIxDuMRm1qFUPpvVjD62vo8azkO0npw4FPcW/I=\"\n\t\t\t}\n\t\t},\n\t\t{\n\t\t\t\"ip\": 1047529523,\n\t\t\t\"port\": 37649,\n\t\t\t\"provided\":\"Neo\",\n\t\t\t\"id\": {\n\t\t\t\t\"@type\": \"pub.ed25519\",\n\t\t\t\t\"key\": \"pRf2sAa7d+Chl8gDclWOMtthtxjKnLYeAIzk869mMvA=\"\n\t\t\t}\n\t\t},\n\t\t{\n\t\t\t\"ip\": 1592601963,\n\t\t\t\"port\": 13833,\n\t\t\t\"id\": {\n\t\t\t\t\"@type\": \"pub.ed25519\",\n\t\t\t\t\"key\": \"QpVqQiv1u3nCHuBR3cg3fT6NqaFLlnLGbEgtBRukDpU=\"\n\t\t\t}\n\t\t},\n\t\t{\n\t\t\t\"ip\": 1162057690,\n\t\t\t\"port\": 35939,\n\t\t\t\"id\": {\n\t\t\t\t\"@type\": \"pub.ed25519\",\n\t\t\t\t\"key\": \"97y55AkdzXWyyVuOAn+WX6p66XTNs2hEGG0jFUOkCIo=\"\n\t\t\t}\n\t\t},\n\t\t{\n\t\t\t\"ip\": -1304477830,\n\t\t\t\"port\": 20700,\n\t\t\t\"id\": {\n\t\t\t\t\"@type\": \"pub.ed25519\",\n\t\t\t\t\"key\": \"dGLlRRai3K9FGkI0dhABmFHMv+92QEVrvmTrFf5fbqA=\"\n\t\t\t}\n\t\t},\n\t\t{\n\t\t\t\"ip\": 1959453117,\n\t\t\t\"port\": 20700,\n\t\t\t\"id\": {\n\t\t\t\t\"@type\": \"pub.ed25519\",\n\t\t\t\t\"key\": \"24RL7iVI20qcG+j//URfd/XFeEG9qtezW2wqaYQgVKw=\"\n\t\t\t}\n\t\t},\n\t\t{\n\t\t\t\"ip\": -809760973,\n\t\t\t\"port\": 20700,\n\t\t\t\"id\": {\n\t\t\t\t\"@type\": \"pub.ed25519\",\n\t\t\t\t\"key\": \"vunMV7K35yPlTQPx/Fqk6s+4/h5lpcbP+ao0Cy3M2hw=\"\n\t\t\t}\n\t\t},\n\t\t{\n\t\t\t\"ip\": 1097633201,\n\t\t\t\"port\": 17439,\n\t\t\t\"id\": {\n\t\t\t\t\"@type\": \"pub.ed25519\",\n\t\t\t\t\"key\": \"0MIADpLH4VQn+INHfm0FxGiuZZAA8JfTujRqQugkkA8=\"\n\t\t\t}\n\t\t},\n\t\t{\n\t\t\t\"ip\": 1091956407,\n\t\t\t\"port\": 16351,\n\t\t\t\"id\": {\n\t\t\t\t\"@type\": \"pub.ed25519\",\n\t\t\t\t\"key\": \"Mf/JGvcWAvcrN3oheze8RF/ps6p7oL6ifrIzFmGQFQ8=\"\n\t\t\t}\n\t\t}\n\t],\n\t\"dht\": {\n\t\t\"a\": 3,\n\t\t\"k\": 3,\n\t\t\"static_nodes\": {\n\t\t\t\"nodes\": [\n\t\t\t\t{\n\t\t\t\t\t\"@type\": \"dht.node\",\n\t\t\t\t\t\"id\": {\n\t\t\t\t\t\t\"@type\": \"pub.ed25519\",\n\t\t\t\t\t\t\"key\": \"K2AWu8leN2RjYmhMpYAaGX/F6nGVk9oZw9c09RX3yyc=\"\n\t\t\t\t\t},\n\t\t\t\t\t\"addr_list\": {\n\t\t\t\t\t\t\"@type\": \"adnl.addressList\",\n\t\t\t\t\t\t\"addrs\": [\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\"@type\": \"adnl.address.udp\",\n\t\t\t\t\t\t\t\t\"ip\": 1592601963,\n\t\t\t\t\t\t\t\t\"port\": 38723\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t],\n\t\t\t\t\t\t\"version\": 0,\n\t\t\t\t\t\t\"reinit_date\": 0,\n\t\t\t\t\t\t\"priority\": 0,\n\t\t\t\t\t\t\"expire_at\": 0\n\t\t\t\t\t},\n\t\t\t\t\t\"version\": -1,\n\t\t\t\t\t\"signature\": \"21g16jxnqbb2ENAijrZFccHqLQcmmpkAI1HA46DaPvnVYvMkATFNEyHTy2R1T1jgU5M7CCLGJN+MxhwZfl/ZDA==\"\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"@type\": \"dht.node\",\n\t\t\t\t\t\"id\": {\n\t\t\t\t\t\t\"@type\": \"pub.ed25519\",\n\t\t\t\t\t\t\"key\": \"fVIJzD9ATMilaPd847eFs6PtGSB67C+D9b4R+nf1+/s=\"\n\t\t\t\t\t},\n\t\t\t\t\t\"addr_list\": {\n\t\t\t\t\t\t\"@type\": \"adnl.addressList\",\n\t\t\t\t\t\t\"addrs\": [\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\"@type\": \"adnl.address.udp\",\n\t\t\t\t\t\t\t\t\"ip\": 1097649206,\n\t\t\t\t\t\t\t\t\"port\": 29081\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t],\n\t\t\t\t\t\t\"version\": 0,\n\t\t\t\t\t\t\"reinit_date\": 0,\n\t\t\t\t\t\t\"priority\": 0,\n\t\t\t\t\t\t\"expire_at\": 0\n\t\t\t\t\t},\n\t\t\t\t\t\"version\": -1,\n\t\t\t\t\t\"signature\": \"wH0HEVT6yAfZZAoD5bF6J3EZWdSFwBGl1ZpOfhxZ0Bp2u52tv8OzjeH8tlZ+geMLTG50Csn5nxSKP1tswTWwBg==\"\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"@type\": \"dht.node\",\n\t\t\t\t\t\"id\": {\n\t\t\t\t\t\t\"@type\": \"pub.ed25519\",\n\t\t\t\t\t\t\"key\": \"gu+woR+x7PoRmaMqAP7oeOjK2V4U0NU8ofdacWZ34aY=\"\n\t\t\t\t\t},\n\t\t\t\t\t\"addr_list\": {\n\t\t\t\t\t\t\"@type\": \"adnl.addressList\",\n\t\t\t\t\t\t\"addrs\": [\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\"@type\": \"adnl.address.udp\",\n\t\t\t\t\t\t\t\t\"ip\": 1162057690,\n\t\t\t\t\t\t\t\t\"port\": 41578\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t],\n\t\t\t\t\t\t\"version\": 0,\n\t\t\t\t\t\t\"reinit_date\": 0,\n\t\t\t\t\t\t\"priority\": 0,\n\t\t\t\t\t\t\"expire_at\": 0\n\t\t\t\t\t},\n\t\t\t\t\t\"version\": -1,\n\t\t\t\t\t\"signature\": \"0PwDLXpN3IbRQuOTLkZBjkbT6+IkeUcvlhWrUY9us3IfSehmCfQjScR9mkVYsQ6cQHF+JeaFmqzV4GAiUcgjAg==\"\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"@type\": \"dht.node\",\n\t\t\t\t\t\"id\": {\n\t\t\t\t\t\t\"@type\": \"pub.ed25519\",\n\t\t\t\t\t\t\"key\": \"WC4BO1eZ916FnLBSKmt07Pn5NP4D3/1wary1VjaCLaY=\"\n\t\t\t\t\t},\n\t\t\t\t\t\"addr_list\": {\n\t\t\t\t\t\t\"@type\": \"adnl.addressList\",\n\t\t\t\t\t\t\"addrs\": [\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\"@type\": \"adnl.address.udp\",\n\t\t\t\t\t\t\t\t\"ip\": -1304477830,\n\t\t\t\t\t\t\t\t\"port\": 9670\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t],\n\t\t\t\t\t\t\"version\": 0,\n\t\t\t\t\t\t\"reinit_date\": 0,\n\t\t\t\t\t\t\"priority\": 0,\n\t\t\t\t\t\t\"expire_at\": 0\n\t\t\t\t\t},\n\t\t\t\t\t\"version\": -1,\n\t\t\t\t\t\"signature\": \"cvpzkGeuEuKV+d92qIVkln9ngm8qeDnmYtK5rq8uSet0392hAZcIv2IniDzTw0rN42NaOHL9A4KEelwKu1N2Ag==\"\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"@type\": \"dht.node\",\n\t\t\t\t\t\"id\": {\n\t\t\t\t\t\t\"@type\": \"pub.ed25519\",\n\t\t\t\t\t\t\"key\": \"nC8dcxV+EV2i0ARvub94IFJKKZUYACfY4xFj1NaG7Pw=\"\n\t\t\t\t\t},\n\t\t\t\t\t\"addr_list\": {\n\t\t\t\t\t\t\"@type\": \"adnl.addressList\",\n\t\t\t\t\t\t\"addrs\": [\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\"@type\": \"adnl.address.udp\",\n\t\t\t\t\t\t\t\t\"ip\": 1959453117,\n\t\t\t\t\t\t\t\t\"port\": 63625\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t],\n\t\t\t\t\t\t\"version\": 0,\n\t\t\t\t\t\t\"reinit_date\": 0,\n\t\t\t\t\t\t\"priority\": 0,\n\t\t\t\t\t\t\"expire_at\": 0\n\t\t\t\t\t},\n\t\t\t\t\t\"version\": -1,\n\t\t\t\t\t\"signature\": \"AHF6joNvQhyFFE0itV4OMA9n3Q8CEHVKapCLqazP7QJ4arsn4pdVkRYiGFEyQkngx+cm8izU4gB0JIaxF6PiBg==\"\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"@type\": \"dht.node\",\n\t\t\t\t\t\"id\": {\n\t\t\t\t\t\t\"@type\": \"pub.ed25519\",\n\t\t\t\t\t\t\"key\": \"dqsRZLzTg/P7uxUlQpgl4VyTBNYBRMc4js3mnRiolBk=\"\n\t\t\t\t\t},\n\t\t\t\t\t\"addr_list\": {\n\t\t\t\t\t\t\"@type\": \"adnl.addressList\",\n\t\t\t\t\t\t\"addrs\": [\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\"@type\": \"adnl.address.udp\",\n\t\t\t\t\t\t\t\t\"ip\": -809760973,\n\t\t\t\t\t\t\t\t\"port\": 40398\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t],\n\t\t\t\t\t\t\"version\": 0,\n\t\t\t\t\t\t\"reinit_date\": 0,\n\t\t\t\t\t\t\"priority\": 0,\n\t\t\t\t\t\t\"expire_at\": 0\n\t\t\t\t\t},\n\t\t\t\t\t\"version\": -1,\n\t\t\t\t\t\"signature\": \"mJxLrAv5RamN5B9mDz6MhQwFjF92D3drJ5efOSZryDaazil0AR4bRHh4vxzZlYiPhi/X/NyG6WwNvKBz+1ntBw==\"\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"@type\": \"dht.node\",\n\t\t\t\t\t\"id\": {\n\t\t\t\t\t\t\"@type\": \"pub.ed25519\",\n\t\t\t\t\t\t\"key\": \"fO6cFYRCRrD+yQzOJdHcNWpRFwu+qLhQnddLq0gGbTs=\"\n\t\t\t\t\t},\n\t\t\t\t\t\"addr_list\": {\n\t\t\t\t\t\t\"@type\": \"adnl.addressList\",\n\t\t\t\t\t\t\"addrs\": [\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\"@type\": \"adnl.address.udp\",\n\t\t\t\t\t\t\t\t\"ip\": 1097633201,\n\t\t\t\t\t\t\t\t\"port\": 7201\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t],\n\t\t\t\t\t\t\"version\": 0,\n\t\t\t\t\t\t\"reinit_date\": 0,\n\t\t\t\t\t\t\"priority\": 0,\n\t\t\t\t\t\t\"expire_at\": 0\n\t\t\t\t\t},\n\t\t\t\t\t\"version\": -1,\n\t\t\t\t\t\"signature\": \"o/rhtiUL3rvA08TKBcCn0DCiSjsNQdAv41aw7VVUig7ubaqJzYMv1cW3qMjxvsXn1BOugIheJm7voA1/brbtCg==\"\n\t\t\t\t}\n\t\t\t],\n\t\t\t\"@type\": \"dht.nodes\"\n\t\t},\n\t\t\"@type\": \"dht.config.global\"\n\t},\n\t\"@type\": \"config.global\",\n\t\"validator\": {\n\t\t\"zero_state\": {\n\t\t\t\"file_hash\": \"Z+IKwYS54DmmJmesw/nAD5DzWadnOCMzee+kdgSYDOg=\",\n\t\t\t\"seqno\": 0,\n\t\t\t\"root_hash\": \"gj+B8wb/AmlPk1z1AhVI484rhrUpgSr2oSFIh56VoSg=\",\n\t\t\t\"workchain\": -1,\n\t\t\t\"shard\": -9223372036854775808\n\t\t},\n\t\t\"@type\": \"validator.config.global\",\n\t\t\"init_block\": {\n\t\t\t\"workchain\": -1,\n\t\t\t\"shard\": -9223372036854775808,\n\t\t\t\"seqno\": 17908219,\n\t\t\t\"root_hash\": \"y6qWqhCnLgzWHjUFmXysaiOljuK5xVoCRMLzUwGInVM=\",\n\t\t\t\"file_hash\": \"Y/GziXxwuYte0AM4WT7tTWsCx+6rcfLpGmRaEQwhUKI=\"\n\t\t},\n\t\t\"hardforks\": [\n\t\t\t{\n\t\t\t\t\"file_hash\": \"jF3RTD+OyOoP+OI9oIjdV6M8EaOh9E+8+c3m5JkPYdg=\",\n\t\t\t\t\"seqno\": 5141579,\n\t\t\t\t\"root_hash\": \"6JSqIYIkW7y8IorxfbQBoXiuY3kXjcoYgQOxTJpjXXA=\",\n\t\t\t\t\"workchain\": -1,\n\t\t\t\t\"shard\": -9223372036854775808\n\t\t\t},\n\t\t\t{\n\t\t\t\t\"file_hash\": \"WrNoMrn5UIVPDV/ug/VPjYatvde8TPvz5v1VYHCLPh8=\",\n\t\t\t\t\"seqno\": 5172980,\n\t\t\t\t\"root_hash\": \"054VCNNtUEwYGoRe1zjH+9b1q21/MeM+3fOo76Vcjes=\",\n\t\t\t\t\"workchain\": -1,\n\t\t\t\t\"shard\": -9223372036854775808\n\t\t\t},\n\t\t\t{\n\t\t\t\t\"file_hash\": \"xRaxgUwgTXYFb16YnR+Q+VVsczLl6jmYwvzhQ/ncrh4=\",\n\t\t\t\t\"seqno\": 5176527,\n\t\t\t\t\"root_hash\": \"SoPLqMe9Dz26YJPOGDOHApTSe5i0kXFtRmRh/zPMGuI=\",\n\t\t\t\t\"workchain\": -1,\n\t\t\t\t\"shard\": -9223372036854775808\n\t\t\t}\n\t\t]\n\t}\n}\n"); + + + LOG(INFO) << "INIT SERVER TUNNEL..."; + // TODO: pass port_ + auto res = PrepareTunnel(&on_recv_batch, callback_.release(), const_cast(cfg.data()), cfg.size(), const_cast(netCfg.data()), netCfg.size()); + LOG(INFO) << "INIT SERVER TUNNEL DONE"; + tunnel_index_ = res.index; + + td:IPAddress ip; + ip.init_ipv4_port(td::IPAddress::ipv4_to_str(res.ip), static_cast(res.port)).ensure(); + on_ready_.set_value(std::move(ip)); + + alarm_timestamp() = td::Timestamp::in(0.05); +} + +void UdpServerTunnelImpl::on_recv_batch(void *next, char *data, size_t num) { + for (size_t i = 0; i < num; i++) { + UdpMessage msg; + msg.address.init_sockaddr(reinterpret_cast(data)); + const uint16_t len = (static_cast(data[16]) << 8) + data[17]; + msg.data = BufferSlice(data+18, len); + data += 18+len; + + // both init_sockaddr and BufferSlice doing memcpy so it is safe + static_cast(next)->on_udp_message(std::move(msg)); + } +} + +td::actor::ActorOwn UdpServerTunnelImpl::create(td::Slice name, int32 port, + std::unique_ptr callback, + td::Promise on_ready) { + return td::actor::create_actor( + actor::ActorOptions().with_name(name).with_poll(!td::Poll::is_edge_triggered()), port, std::move(callback), std::move(on_ready)); +} + +UdpServerTunnelImpl::UdpServerTunnelImpl(int32 port, std::unique_ptr callback, td::Promise on_ready): port_(port), callback_(std::move(callback)), on_ready_(std::move(on_ready)) { +} + class UdpServerImpl : public UdpServer { public: void send(td::UdpMessage &&message) override; @@ -396,6 +510,13 @@ Result> UdpServer::create(td::Slice name, int32 port, fd.maximize_rcv_buffer().ensure(); return detail::UdpServerImpl::create(name, std::move(fd), std::move(callback)); } + +Result> UdpServer::create_via_tunnel(td::Slice name, int32 port, + std::unique_ptr callback, + td::Promise on_ready) { + return detail::UdpServerTunnelImpl::create(name, port, std::move(callback), std::move(on_ready)); +} + Result> UdpServer::create_via_tcp(td::Slice name, int32 port, std::unique_ptr callback) { return actor::create_actor(name, port, std::move(callback)); diff --git a/tdnet/td/net/UdpServer.h b/tdnet/td/net/UdpServer.h index f6d0d268..4219f4a1 100644 --- a/tdnet/td/net/UdpServer.h +++ b/tdnet/td/net/UdpServer.h @@ -37,6 +37,10 @@ class UdpServer : public td::actor::Actor { static Result> create(td::Slice name, int32 port, std::unique_ptr callback); static Result> create_via_tcp(td::Slice name, int32 port, std::unique_ptr callback); + static Result> create_via_tunnel(td::Slice name, int32 port, + std::unique_ptr callback, + td::Promise on_ready); + }; } // namespace td diff --git a/tdnet/td/net/tunnel/libtunnel.h b/tdnet/td/net/tunnel/libtunnel.h new file mode 100644 index 00000000..3d48b01b --- /dev/null +++ b/tdnet/td/net/tunnel/libtunnel.h @@ -0,0 +1,104 @@ +/* Code generated by cmd/cgo; DO NOT EDIT. */ + +/* package command-line-arguments */ + + +#line 1 "cgo-builtin-export-prolog" + +#include + +#ifndef GO_CGO_EXPORT_PROLOGUE_H +#define GO_CGO_EXPORT_PROLOGUE_H + +#ifndef GO_CGO_GOSTRING_TYPEDEF +typedef struct { const char *p; ptrdiff_t n; } _GoString_; +#endif + +#endif + +/* Start of preamble from import "C" comments. */ + + +#line 3 "lib.go" + +typedef struct { + size_t index; + int ip; + int port; +} Tunnel; + +// next - is pointer to class instance or callback to call method from node code +typedef void (*RecvCallback)(void* next, char * data, size_t num); + +typedef void (*PullSendCallback)(void* next, char * data, size_t num); + + +// we need it because we cannot call C func by pointer directly from go +static inline void on_recv_batch_ready(RecvCallback cb, void* next, void* data, size_t num) { + cb(next, (char*)data, num); +} + +#line 1 "cgo-generated-wrapper" + + +/* End of preamble from import "C" comments. */ + + +/* Start of boilerplate cgo prologue. */ +#line 1 "cgo-gcc-export-header-prolog" + +#ifndef GO_CGO_PROLOGUE_H +#define GO_CGO_PROLOGUE_H + +typedef signed char GoInt8; +typedef unsigned char GoUint8; +typedef short GoInt16; +typedef unsigned short GoUint16; +typedef int GoInt32; +typedef unsigned int GoUint32; +typedef long long GoInt64; +typedef unsigned long long GoUint64; +typedef GoInt64 GoInt; +typedef GoUint64 GoUint; +typedef size_t GoUintptr; +typedef float GoFloat32; +typedef double GoFloat64; +#ifdef _MSC_VER +#include +typedef _Fcomplex GoComplex64; +typedef _Dcomplex GoComplex128; +#else +typedef float _Complex GoComplex64; +typedef double _Complex GoComplex128; +#endif + +/* + static assertion to make sure the file is being used on architecture + at least with matching size of GoInt. +*/ +typedef char _check_for_64_bit_pointer_matching_GoInt[sizeof(void*)==64/8 ? 1:-1]; + +#ifndef GO_CGO_GOSTRING_TYPEDEF +typedef _GoString_ GoString; +#endif +typedef void *GoMap; +typedef void *GoChan; +typedef struct { void *t; void *v; } GoInterface; +typedef struct { void *data; GoInt len; GoInt cap; } GoSlice; + +#endif + +/* End of boilerplate cgo prologue. */ + +#ifdef __cplusplus +extern "C" { +#endif + + +//goland:noinspection ALL +extern Tunnel PrepareTunnel(RecvCallback onRecv, void* next, char* configJson, int configJsonLen, char* networkConfigJson, int networkConfigJsonLen); +extern int WriteTunnel(size_t tunIdx, char* data, size_t num); + +#ifdef __cplusplus +} +#endif diff --git a/tl/generate/scheme/ton_api.tl b/tl/generate/scheme/ton_api.tl index cfc9f3a1..75e5c298 100644 --- a/tl/generate/scheme/ton_api.tl +++ b/tl/generate/scheme/ton_api.tl @@ -648,7 +648,7 @@ engine.validator.fullNodeMaster port:int adnl:int256 = engine.validator.FullNode engine.validator.fullNodeSlave ip:int port:int adnl:PublicKey = engine.validator.FullNodeSlave; engine.validator.fullNodeConfig ext_messages_broadcast_disabled:Bool = engine.validator.FullNodeConfig; engine.validator.extraConfig state_serializer_enabled:Bool = engine.validator.ExtraConfig; -engine.validator.config out_port:int addrs:(vector engine.Addr) adnl:(vector engine.adnl) +engine.validator.config out_port:int tunnel_enabled:int addrs:(vector engine.Addr) adnl:(vector engine.adnl) dht:(vector engine.dht) validators:(vector engine.validator) fullnode:int256 fullnodeslaves:(vector engine.validator.fullNodeSlave) fullnodemasters:(vector engine.validator.fullNodeMaster) diff --git a/tl/generate/scheme/ton_api.tlo b/tl/generate/scheme/ton_api.tlo index 96ecb7751b1ad3a31830cba56037d0037988cde3..a6d86030aa00f69ed45f1a416dd3d7fe78573b78 100644 GIT binary patch delta 82 zcmcbzfbGu$whb3VS@cz&eb{_ObV)xeh$TKbafJv^T4p+kbMu&x5C3$>Xhv;*zLL_s fywsfd)V#!`oYa)b`yHeAKiRKbV)y$HMwS~1Sd%7<}o23zUhTQj5?b?E^TIlD63e( G@&W+;{27%1 diff --git a/validator-engine/validator-engine.cpp b/validator-engine/validator-engine.cpp index cc7c57b3..dc91b24a 100644 --- a/validator-engine/validator-engine.cpp +++ b/validator-engine/validator-engine.cpp @@ -88,6 +88,7 @@ Config::Config() { Config::Config(const ton::ton_api::engine_validator_config &config) { full_node = ton::PublicKeyHash::zero(); out_port = static_cast(config.out_port_); + tunnel_enabled = true; //static_cast(config.tunnel_enabled_); if (!out_port) { out_port = 3278; } @@ -278,7 +279,7 @@ ton::tl_object_ptr Config::tl() const { } return ton::create_tl_object( - out_port, std::move(addrs_vec), std::move(adnl_vec), std::move(dht_vec), std::move(val_vec), + out_port, 0, std::move(addrs_vec), std::move(adnl_vec), std::move(dht_vec), std::move(val_vec), full_node.tl(), std::move(full_node_slaves_vec), std::move(full_node_masters_vec), std::move(full_node_config_obj), std::move(extra_config_obj), std::move(liteserver_vec), std::move(control_vec), std::move(shards_vec), std::move(gc_vec)); @@ -1848,6 +1849,39 @@ void ValidatorEngine::start_adnl() { adnl_ = ton::adnl::Adnl::create(db_root_, keyring_.get()); td::actor::send_closure(adnl_, &ton::adnl::Adnl::register_network_manager, adnl_network_manager_.get()); + if (config_.tunnel_enabled) { + auto on_tunnel_ready = td::PromiseCreator::lambda([SelfId = actor_id(this), this, ip](td::Result R) { + R.ensure(); + auto addr = R.move_as_ok(); + + LOG(INFO) << "Tunnel ready, addr: " << addr; + + add_addr(Config::Addr{}, Config::AddrCats{ + .in_addr = addr, + .is_tunnel = true, + .cats = {0, 1, 2, 3}, + }); + + for (auto &adnl : config_.adnl_ids) { + add_adnl(adnl.first, adnl.second); + } + + td::actor::send_closure(adnl_, &ton::adnl::Adnl::add_static_nodes_from_config, std::move(adnl_static_nodes_)); + td::actor::send_closure(SelfId, &ValidatorEngine::started_adnl); + }); + + ton::adnl::AdnlCategoryMask cat_mask; + cat_mask[0] = true; + cat_mask[1] = true; + cat_mask[2] = true; + cat_mask[3] = true; + + td::actor::send_closure(adnl_network_manager_, &ton::adnl::AdnlNetworkManager::add_tunnel, 3433, + std::move(cat_mask), 0, std::move(on_tunnel_ready)); + + return; + } + for (auto &addr : config_.addrs) { add_addr(addr.first, addr.second); } @@ -1867,13 +1901,16 @@ void ValidatorEngine::add_addr(const Config::Addr &addr, const Config::AddrCats for (auto cat : cats.priority_cats) { cat_mask[cat] = true; } - if (!cats.proxy) { - td::actor::send_closure(adnl_network_manager_, &ton::adnl::AdnlNetworkManager::add_self_addr, addr.addr, - std::move(cat_mask), cats.cats.size() ? 0 : 1); - } else { - td::actor::send_closure(adnl_network_manager_, &ton::adnl::AdnlNetworkManager::add_proxy_addr, cats.in_addr, - static_cast(addr.addr.get_port()), cats.proxy, std::move(cat_mask), - cats.cats.size() ? 0 : 1); + + if (!cats.is_tunnel) { + if (!cats.proxy) { + td::actor::send_closure(adnl_network_manager_, &ton::adnl::AdnlNetworkManager::add_self_addr, addr.addr, + std::move(cat_mask), cats.cats.size() ? 0 : 1); + } else { + td::actor::send_closure(adnl_network_manager_, &ton::adnl::AdnlNetworkManager::add_proxy_addr, cats.in_addr, + static_cast(addr.addr.get_port()), cats.proxy, std::move(cat_mask), + cats.cats.size() ? 0 : 1); + } } td::uint32 ts = static_cast(td::Clocks::system()); diff --git a/validator-engine/validator-engine.hpp b/validator-engine/validator-engine.hpp index b7abb0b1..3b79564d 100644 --- a/validator-engine/validator-engine.hpp +++ b/validator-engine/validator-engine.hpp @@ -57,6 +57,7 @@ struct Config { }; struct AddrCats { td::IPAddress in_addr; + bool is_tunnel; std::shared_ptr proxy; std::set cats; std::set priority_cats; @@ -78,6 +79,7 @@ struct Config { std::map keys_refcnt; td::uint16 out_port; + bool tunnel_enabled; std::map addrs; std::map adnl_ids; std::set dht_ids; From 1d800cdd2029524293527a4cd79206f0ed40809b Mon Sep 17 00:00:00 2001 From: Oleg Baranov Date: Thu, 20 Feb 2025 10:35:18 +0400 Subject: [PATCH 02/13] Fixed test loopback header --- adnl/adnl-test-loopback-implementation.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/adnl/adnl-test-loopback-implementation.h b/adnl/adnl-test-loopback-implementation.h index 4773f053..093d07cc 100644 --- a/adnl/adnl-test-loopback-implementation.h +++ b/adnl/adnl-test-loopback-implementation.h @@ -39,6 +39,9 @@ class TestLoopbackNetworkManager : public ton::adnl::AdnlNetworkManager { void add_proxy_addr(td::IPAddress addr, td::uint16 local_port, std::shared_ptr proxy, AdnlCategoryMask cat_mask, td::uint32 priority) override { } + void add_tunnel(td::uint16 port, AdnlCategoryMask cat_mask, td::uint32 priority, + td::Promise on_ready) 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 { if (allowed_sources_.count(src_id) == 0 || allowed_destinations_.count(dst_id) == 0) { From 08b6ccb7834192a76221b8fc2b08c24df54c4885 Mon Sep 17 00:00:00 2001 From: Oleg Baranov Date: Thu, 20 Feb 2025 10:38:09 +0400 Subject: [PATCH 03/13] Removed ip var from tun init --- validator-engine/validator-engine.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/validator-engine/validator-engine.cpp b/validator-engine/validator-engine.cpp index dc91b24a..d06add2a 100644 --- a/validator-engine/validator-engine.cpp +++ b/validator-engine/validator-engine.cpp @@ -1850,7 +1850,7 @@ void ValidatorEngine::start_adnl() { td::actor::send_closure(adnl_, &ton::adnl::Adnl::register_network_manager, adnl_network_manager_.get()); if (config_.tunnel_enabled) { - auto on_tunnel_ready = td::PromiseCreator::lambda([SelfId = actor_id(this), this, ip](td::Result R) { + auto on_tunnel_ready = td::PromiseCreator::lambda([SelfId = actor_id(this), this](td::Result R) { R.ensure(); auto addr = R.move_as_ok(); From d287bafa1513190957efc3448911f7aff572861d Mon Sep 17 00:00:00 2001 From: Oleg Baranov Date: Thu, 20 Feb 2025 10:41:45 +0400 Subject: [PATCH 04/13] Fixed dht default config init --- dht-server/dht-server.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dht-server/dht-server.cpp b/dht-server/dht-server.cpp index fa9fad13..d7bb84e0 100644 --- a/dht-server/dht-server.cpp +++ b/dht-server/dht-server.cpp @@ -169,7 +169,7 @@ ton::tl_object_ptr Config::tl() const { gc_vec->ids_.push_back(id.tl()); } return ton::create_tl_object( - out_port, std::move(addrs_vec), std::move(adnl_vec), std::move(dht_vec), std::move(val_vec), + out_port, 0, std::move(addrs_vec), std::move(adnl_vec), std::move(dht_vec), std::move(val_vec), ton::PublicKeyHash::zero().tl(), std::move(full_node_slaves_vec), std::move(full_node_masters_vec), nullptr, nullptr, std::move(liteserver_vec), std::move(control_vec), std::move(shard_vec), std::move(gc_vec)); } From 374e75932f8c4e5105f4555132a46cce5f81c75d Mon Sep 17 00:00:00 2001 From: Oleg Baranov Date: Tue, 25 Feb 2025 16:04:32 +0400 Subject: [PATCH 05/13] Tunnel reinit support + Fixed packets recv through tunnel --- adnl/adnl-network-manager.cpp | 43 +++++++---- adnl/adnl-network-manager.h | 12 ++- adnl/adnl-network-manager.hpp | 11 ++- adnl/adnl-test-loopback-implementation.h | 6 +- tdnet/td/net/UdpServer.cpp | 94 +++++++++++++++-------- tdnet/td/net/UdpServer.h | 10 ++- tdnet/td/net/tunnel/libtunnel.h | 17 ++-- tl/generate/scheme/ton_api.tl | 2 +- tl/generate/scheme/ton_api.tlo | Bin 102524 -> 102484 bytes validator-engine/validator-engine.cpp | 55 ++++++++++--- validator-engine/validator-engine.hpp | 7 +- 11 files changed, 177 insertions(+), 80 deletions(-) diff --git a/adnl/adnl-network-manager.cpp b/adnl/adnl-network-manager.cpp index ba5d9208..99a74eb3 100644 --- a/adnl/adnl-network-manager.cpp +++ b/adnl/adnl-network-manager.cpp @@ -76,32 +76,43 @@ size_t AdnlNetworkManagerImpl::add_listening_udp_port(td::uint16 port) { return idx; } -size_t AdnlNetworkManagerImpl::add_tunnel_udp_port(td::uint16 port, td::Promise on_ready) { - auto it = port_2_socket_.find(port); +#define TUNNEL_FAKE_PORT 1 + +size_t AdnlNetworkManagerImpl::add_tunnel_udp_port(std::string global_config, std::string tunnel_config, td::Promise on_ready, + td::actor::Scheduler *scheduler) { + auto it = port_2_socket_.find(TUNNEL_FAKE_PORT); if (it != port_2_socket_.end()) { return it->second; } - class Callback : public td::UdpServer::Callback { + class Callback : public td::UdpServer::TunnelCallback { public: - Callback(td::actor::ActorShared manager, size_t idx) - : manager_(std::move(manager)), idx_(idx) { + Callback(td::actor::ActorShared manager, size_t idx, td::actor::Scheduler *scheduler, TunnelEventsHandler* tunnel_events_handler) + : manager_(std::move(manager)), idx_(idx), scheduler_(scheduler), tunnel_events_handler_(tunnel_events_handler) { } private: + TunnelEventsHandler* tunnel_events_handler_; td::actor::ActorShared manager_; size_t idx_; + td::actor::Scheduler *scheduler_; void on_udp_message(td::UdpMessage udp_message) override { - td::actor::send_closure_later(manager_, &AdnlNetworkManagerImpl::receive_udp_message, std::move(udp_message), - idx_); + scheduler_->run_in_context_external([&] { + td::actor::send_closure_later(manager_, &AdnlNetworkManagerImpl::receive_udp_message, std::move(udp_message), + idx_); + }); + } + void on_in_addr_update(const td::IPAddress ip) override { + tunnel_events_handler_->on_in_addr_update(ip); } }; auto idx = udp_sockets_.size(); - auto X = td::UdpServer::create_via_tunnel("udp tunnel server", port, - std::make_unique(actor_shared(this), idx), std::move(on_ready)); + auto X = td::UdpServer::create_via_tunnel("udp tunnel server", global_config, tunnel_config, + std::make_unique(actor_shared(this), idx, scheduler, tunnel_events_handler_.get()), + std::move(on_ready)); X.ensure(); - port_2_socket_[port] = idx; - udp_sockets_.push_back(UdpSocketDesc{port, X.move_as_ok()}); + port_2_socket_[TUNNEL_FAKE_PORT] = idx; + udp_sockets_.push_back(UdpSocketDesc{TUNNEL_FAKE_PORT, X.move_as_ok()}); return idx; } @@ -121,12 +132,12 @@ void AdnlNetworkManagerImpl::add_self_addr(td::IPAddress addr, AdnlCategoryMask out_desc_[priority].push_back(std::move(d)); } -void AdnlNetworkManagerImpl::add_tunnel(td::uint16 port, AdnlCategoryMask cat_mask, td::uint32 priority, - td::Promise on_ready) { - size_t idx = add_tunnel_udp_port(port, std::move(on_ready)); +void AdnlNetworkManagerImpl::add_tunnel(std::string global_config, std::string tunnel_config, AdnlCategoryMask cat_mask, td::uint32 priority, + td::Promise on_ready, td::actor::Scheduler *scheduler) { + size_t idx = add_tunnel_udp_port(global_config, tunnel_config, std::move(on_ready), scheduler); - add_in_addr(InDesc{port, nullptr, cat_mask}, idx); - auto d = OutDesc{port, td::IPAddress{}, nullptr, idx}; + add_in_addr(InDesc{TUNNEL_FAKE_PORT, nullptr, cat_mask}, idx); + auto d = OutDesc{TUNNEL_FAKE_PORT, td::IPAddress{}, nullptr, idx}; for (auto &it : out_desc_[priority]) { if (it == d) { it.cat_mask |= cat_mask; diff --git a/adnl/adnl-network-manager.h b/adnl/adnl-network-manager.h index 6d439a12..d94d5337 100644 --- a/adnl/adnl-network-manager.h +++ b/adnl/adnl-network-manager.h @@ -59,19 +59,25 @@ class AdnlNetworkManager : public td::actor::Actor { public: //using ConnHandle = td::uint64; class Callback { - public: + 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, AdnlCategoryMask cat_mask, td::BufferSlice data) = 0; }; + class TunnelEventsHandler { + public: + virtual ~TunnelEventsHandler() = default; + virtual void on_in_addr_update(td::IPAddress ip) = 0; + }; static td::actor::ActorOwn create(td::uint16 out_port); virtual ~AdnlNetworkManager() = default; virtual void install_callback(std::unique_ptr callback) = 0; + virtual void install_tunnel_events_handler(std::unique_ptr handler) = 0; - virtual void add_tunnel(td::uint16 port, AdnlCategoryMask cat_mask, td::uint32 priority, - td::Promise on_ready) = 0; + virtual void add_tunnel(std::string global_config, std::string tunnel_config, AdnlCategoryMask cat_mask, td::uint32 priority, + td::Promise on_ready, td::actor::Scheduler *scheduler) = 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 proxy, AdnlCategoryMask cat_mask, td::uint32 priority) = 0; diff --git a/adnl/adnl-network-manager.hpp b/adnl/adnl-network-manager.hpp index 30a9efc8..4f7f4212 100644 --- a/adnl/adnl-network-manager.hpp +++ b/adnl/adnl-network-manager.hpp @@ -109,6 +109,10 @@ class AdnlNetworkManagerImpl : public AdnlNetworkManager { callback_ = std::move(callback); } + void install_tunnel_events_handler(std::unique_ptr handler) override { + tunnel_events_handler_ = std::move(handler); + } + void alarm() override; void start_up() override { alarm_timestamp() = td::Timestamp::in(60.0); @@ -131,8 +135,8 @@ class AdnlNetworkManagerImpl : public AdnlNetworkManager { in_desc_.push_back(std::move(desc)); } - void add_tunnel(td::uint16 port, AdnlCategoryMask cat_mask, td::uint32 priority, - td::Promise on_ready) override; + void add_tunnel(std::string global_config, std::string tunnel_config, AdnlCategoryMask cat_mask, td::uint32 priority, td::Promise on_ready, + td::actor::Scheduler *scheduler) override; 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 proxy, AdnlCategoryMask cat_mask, td::uint32 priority) override; @@ -147,13 +151,14 @@ class AdnlNetworkManagerImpl : public AdnlNetworkManager { } } - size_t add_tunnel_udp_port(td::uint16 port, td::Promise on_ready); + size_t add_tunnel_udp_port(std::string global_config, std::string tunnel_config, td::Promise on_ready, td::actor::Scheduler *scheduler); 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_; + std::unique_ptr tunnel_events_handler_; std::map> out_desc_; std::vector in_desc_; diff --git a/adnl/adnl-test-loopback-implementation.h b/adnl/adnl-test-loopback-implementation.h index 093d07cc..c2ff3207 100644 --- a/adnl/adnl-test-loopback-implementation.h +++ b/adnl/adnl-test-loopback-implementation.h @@ -34,13 +34,15 @@ class TestLoopbackNetworkManager : public ton::adnl::AdnlNetworkManager { callback_ = std::move(callback); } + void install_tunnel_events_handler(std::unique_ptr handler) override {}; + 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 proxy, AdnlCategoryMask cat_mask, td::uint32 priority) override { } - void add_tunnel(td::uint16 port, AdnlCategoryMask cat_mask, td::uint32 priority, - td::Promise on_ready) override { + void add_tunnel(std::string global_config, std::string tunnel_config, AdnlCategoryMask cat_mask, td::uint32 priority, td::Promise on_ready, + td::actor::Scheduler* scheduler) 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 { diff --git a/tdnet/td/net/UdpServer.cpp b/tdnet/td/net/UdpServer.cpp index 4e3e8ff5..c90a2ca2 100644 --- a/tdnet/td/net/UdpServer.cpp +++ b/tdnet/td/net/UdpServer.cpp @@ -23,6 +23,7 @@ #include "td/net/tunnel/libtunnel.h" #include "td/utils/BufferedFd.h" +#include "td/utils/filesystem.h" #include @@ -38,23 +39,27 @@ class UdpServerTunnelImpl : public UdpServer { void alarm() override; void send(td::UdpMessage &&message) override; - static td::actor::ActorOwn create(td::Slice name, int32 port, std::unique_ptr callback, + static td::actor::ActorOwn create(td::Slice name, std::string global_config, std::string tunnel_config, std::unique_ptr callback, td::Promise on_ready); - UdpServerTunnelImpl(int32 port, std::unique_ptr callback, td::Promise on_ready); + UdpServerTunnelImpl(std::string global_config, std::string tunnel_config, std::unique_ptr callback, td::Promise on_ready); private: td::Promise on_ready_; - char out_buf_[(16+2+1500)*300]; + uint8_t out_buf_[(16+2+1500)*300]; size_t out_buf_offset_ = 0; size_t out_buf_msg_num_ = 0; size_t tunnel_index_; double last_batch_at_ = Time::now(); - int32 port_; - std::unique_ptr callback_; + std::string global_config_; + std::string tunnel_config_; - static void on_recv_batch(void *next, char *data, size_t num); + int32 port_; + std::unique_ptr callback_; + + static void on_recv_batch(void *next, uint8_t *data, size_t num); + static void on_reinit(void *next, sockaddr *addr); }; @@ -67,8 +72,8 @@ void UdpServerTunnelImpl::send(td::UdpMessage &&message) { out_buf_offset_ += sizeof(sockaddr); // data len (2 bytes) - out_buf_[out_buf_offset_] = static_cast(sz >> 8); - out_buf_[out_buf_offset_ + 1] = static_cast(sz & 0xff); + out_buf_[out_buf_offset_] = static_cast(sz >> 8); + out_buf_[out_buf_offset_ + 1] = static_cast(sz & 0xff); memcpy(out_buf_ + out_buf_offset_ + 2, message.data.data(), sz); out_buf_offset_ += 2 + sz; @@ -78,69 +83,90 @@ void UdpServerTunnelImpl::send(td::UdpMessage &&message) { if (out_buf_msg_num_ >= 100) { td::Timer timer; WriteTunnel(tunnel_index_, out_buf_, out_buf_msg_num_); - LOG(INFO) << "Sending messages " << out_buf_msg_num_ << " | " << timer.elapsed(); out_buf_offset_ = 0; out_buf_msg_num_ = 0; last_batch_at_ = Time::now(); } - // LOG(INFO) << "TUN message to: "; } void UdpServerTunnelImpl::alarm() { auto now = Time::now(); - if (out_buf_msg_num_ > 0 && now-last_batch_at_ > 0.02) { + if (out_buf_msg_num_ > 0 && now-last_batch_at_ >= 0.02) { td::Timer timer; WriteTunnel(tunnel_index_, out_buf_, out_buf_msg_num_); - LOG(ERROR) << "Sending messages from alarm " << out_buf_msg_num_ << " | " << timer.elapsed(); + // LOG(ERROR) << "Sending messages from alarm " << out_buf_msg_num_ << " | " << timer.elapsed(); out_buf_offset_ = 0; out_buf_msg_num_ = 0; last_batch_at_ = now; } - alarm_timestamp() = td::Timestamp::in(0.05); + alarm_timestamp() = td::Timestamp::in(0.02); } void UdpServerTunnelImpl::start_up() { - auto cfg = Slice("{\n\t\t\"TunnelServerKey\": \"2Kg9YuGSbpPA8+2UlMyef47UOzFt7fFjz9QREGUhP0U=\",\n\t\t\"TunnelThreads\": 10,\n\t\t\"PaymentsEnabled\": false,\n\t\t\"Payments\": {\n\t\t\t\"PaymentsServerKey\": \"8BfanhwJYWRlASVw6mXeuUxoMyB73CDfHYLQ8mF5FxE=\",\n\t\t\t\"WalletPrivateKey\": \"8BfanhwJYWRlASVw6mXeuUxoMyB73CDfHYLQ8mF5FxA=\",\n\t\t\t\"PaymentsListenAddr\": \"0.0.0.0:13131\",\n\t\t\t\"DBPath\": \"./payments-db/\",\n\t\t\t\"SecureProofPolicy\": false,\n\t\t\t\"ChannelConfig\": {\n\t\t\t\t\"VirtualChannelProxyFee\": \"0.01\",\n\t\t\t\t\"QuarantineDurationSec\": 600,\n\t\t\t\t\"MisbehaviorFine\": \"0.15\",\n\t\t\t\t\"ConditionalCloseDurationSec\": 180\n\t\t\t}\n\t\t},\n\t\t\"OutGateway\": {\n\t\t\t\"Key\": \"cKrWi/IgAKvd3Ro92ap2IfKABX3C4rQI59P+v1g+vOg=\",\n\t\t\t\"Payment\": null},\n\t\t\"RouteOut\": [],\n\t\t\"RouteIn\": []\n\t}"); - auto netCfg = Slice("{\n\t\"liteservers\": [\n\t\t{\n\t\t\t\"ip\": 822907680,\n\t\t\t\"port\": 27842,\n\t\t\t\"provided\":\"Beavis\",\n\t\t\t\"id\": {\n\t\t\t\t\"@type\": \"pub.ed25519\",\n\t\t\t\t\"key\": \"sU7QavX2F964iI9oToP9gffQpCQIoOLppeqL/pdPvpM=\"\n\t\t\t}\n\t\t},\n\t\t{\n\t\t\t\"ip\": -1468571697,\n\t\t\t\"port\": 27787,\n\t\t\t\"provided\":\"Beavis\",\n\t\t\t\"id\": {\n\t\t\t\t\"@type\": \"pub.ed25519\",\n\t\t\t\t\"key\": \"Y/QVf6G5VDiKTZOKitbFVm067WsuocTN8Vg036A4zGk=\"\n\t\t\t}\n\t\t},\n\t\t{\n\t\t\t\"ip\": -1468575011,\n\t\t\t\"port\": 51088,\n\t\t\t\"provided\":\"Beavis\",\n\t\t\t\"id\": {\n\t\t\t\t\"@type\": \"pub.ed25519\",\n\t\t\t\t\"key\": \"Sy5ghr3EahQd/1rDayzZXt5+inlfF+7kLfkZDJcU/ek=\"\n\t\t\t}\n\t\t},\n\t\t{\n\t\t\t\"ip\": 1844203537,\n\t\t\t\"port\": 37537,\n\t\t\t\"provided\":\"Neo\",\n\t\t\t\"id\": {\n\t\t\t\t\"@type\": \"pub.ed25519\",\n\t\t\t\t\"key\": \"K1F7zEe0ETf+SwkefLS56hJE8x42sjCVsBJJuaY7nEA=\"\n\t\t\t}\n\t\t},\n\t\t{\n\t\t\t\"ip\": 1844203589,\n\t\t\t\"port\": 34411,\n\t\t\t\"provided\":\"Neo\",\n\t\t\t\"id\": {\n\t\t\t\t\"@type\": \"pub.ed25519\",\n\t\t\t\t\"key\": \"pOpRRpIxDuMRm1qFUPpvVjD62vo8azkO0npw4FPcW/I=\"\n\t\t\t}\n\t\t},\n\t\t{\n\t\t\t\"ip\": 1047529523,\n\t\t\t\"port\": 37649,\n\t\t\t\"provided\":\"Neo\",\n\t\t\t\"id\": {\n\t\t\t\t\"@type\": \"pub.ed25519\",\n\t\t\t\t\"key\": \"pRf2sAa7d+Chl8gDclWOMtthtxjKnLYeAIzk869mMvA=\"\n\t\t\t}\n\t\t},\n\t\t{\n\t\t\t\"ip\": 1592601963,\n\t\t\t\"port\": 13833,\n\t\t\t\"id\": {\n\t\t\t\t\"@type\": \"pub.ed25519\",\n\t\t\t\t\"key\": \"QpVqQiv1u3nCHuBR3cg3fT6NqaFLlnLGbEgtBRukDpU=\"\n\t\t\t}\n\t\t},\n\t\t{\n\t\t\t\"ip\": 1162057690,\n\t\t\t\"port\": 35939,\n\t\t\t\"id\": {\n\t\t\t\t\"@type\": \"pub.ed25519\",\n\t\t\t\t\"key\": \"97y55AkdzXWyyVuOAn+WX6p66XTNs2hEGG0jFUOkCIo=\"\n\t\t\t}\n\t\t},\n\t\t{\n\t\t\t\"ip\": -1304477830,\n\t\t\t\"port\": 20700,\n\t\t\t\"id\": {\n\t\t\t\t\"@type\": \"pub.ed25519\",\n\t\t\t\t\"key\": \"dGLlRRai3K9FGkI0dhABmFHMv+92QEVrvmTrFf5fbqA=\"\n\t\t\t}\n\t\t},\n\t\t{\n\t\t\t\"ip\": 1959453117,\n\t\t\t\"port\": 20700,\n\t\t\t\"id\": {\n\t\t\t\t\"@type\": \"pub.ed25519\",\n\t\t\t\t\"key\": \"24RL7iVI20qcG+j//URfd/XFeEG9qtezW2wqaYQgVKw=\"\n\t\t\t}\n\t\t},\n\t\t{\n\t\t\t\"ip\": -809760973,\n\t\t\t\"port\": 20700,\n\t\t\t\"id\": {\n\t\t\t\t\"@type\": \"pub.ed25519\",\n\t\t\t\t\"key\": \"vunMV7K35yPlTQPx/Fqk6s+4/h5lpcbP+ao0Cy3M2hw=\"\n\t\t\t}\n\t\t},\n\t\t{\n\t\t\t\"ip\": 1097633201,\n\t\t\t\"port\": 17439,\n\t\t\t\"id\": {\n\t\t\t\t\"@type\": \"pub.ed25519\",\n\t\t\t\t\"key\": \"0MIADpLH4VQn+INHfm0FxGiuZZAA8JfTujRqQugkkA8=\"\n\t\t\t}\n\t\t},\n\t\t{\n\t\t\t\"ip\": 1091956407,\n\t\t\t\"port\": 16351,\n\t\t\t\"id\": {\n\t\t\t\t\"@type\": \"pub.ed25519\",\n\t\t\t\t\"key\": \"Mf/JGvcWAvcrN3oheze8RF/ps6p7oL6ifrIzFmGQFQ8=\"\n\t\t\t}\n\t\t}\n\t],\n\t\"dht\": {\n\t\t\"a\": 3,\n\t\t\"k\": 3,\n\t\t\"static_nodes\": {\n\t\t\t\"nodes\": [\n\t\t\t\t{\n\t\t\t\t\t\"@type\": \"dht.node\",\n\t\t\t\t\t\"id\": {\n\t\t\t\t\t\t\"@type\": \"pub.ed25519\",\n\t\t\t\t\t\t\"key\": \"K2AWu8leN2RjYmhMpYAaGX/F6nGVk9oZw9c09RX3yyc=\"\n\t\t\t\t\t},\n\t\t\t\t\t\"addr_list\": {\n\t\t\t\t\t\t\"@type\": \"adnl.addressList\",\n\t\t\t\t\t\t\"addrs\": [\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\"@type\": \"adnl.address.udp\",\n\t\t\t\t\t\t\t\t\"ip\": 1592601963,\n\t\t\t\t\t\t\t\t\"port\": 38723\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t],\n\t\t\t\t\t\t\"version\": 0,\n\t\t\t\t\t\t\"reinit_date\": 0,\n\t\t\t\t\t\t\"priority\": 0,\n\t\t\t\t\t\t\"expire_at\": 0\n\t\t\t\t\t},\n\t\t\t\t\t\"version\": -1,\n\t\t\t\t\t\"signature\": \"21g16jxnqbb2ENAijrZFccHqLQcmmpkAI1HA46DaPvnVYvMkATFNEyHTy2R1T1jgU5M7CCLGJN+MxhwZfl/ZDA==\"\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"@type\": \"dht.node\",\n\t\t\t\t\t\"id\": {\n\t\t\t\t\t\t\"@type\": \"pub.ed25519\",\n\t\t\t\t\t\t\"key\": \"fVIJzD9ATMilaPd847eFs6PtGSB67C+D9b4R+nf1+/s=\"\n\t\t\t\t\t},\n\t\t\t\t\t\"addr_list\": {\n\t\t\t\t\t\t\"@type\": \"adnl.addressList\",\n\t\t\t\t\t\t\"addrs\": [\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\"@type\": \"adnl.address.udp\",\n\t\t\t\t\t\t\t\t\"ip\": 1097649206,\n\t\t\t\t\t\t\t\t\"port\": 29081\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t],\n\t\t\t\t\t\t\"version\": 0,\n\t\t\t\t\t\t\"reinit_date\": 0,\n\t\t\t\t\t\t\"priority\": 0,\n\t\t\t\t\t\t\"expire_at\": 0\n\t\t\t\t\t},\n\t\t\t\t\t\"version\": -1,\n\t\t\t\t\t\"signature\": \"wH0HEVT6yAfZZAoD5bF6J3EZWdSFwBGl1ZpOfhxZ0Bp2u52tv8OzjeH8tlZ+geMLTG50Csn5nxSKP1tswTWwBg==\"\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"@type\": \"dht.node\",\n\t\t\t\t\t\"id\": {\n\t\t\t\t\t\t\"@type\": \"pub.ed25519\",\n\t\t\t\t\t\t\"key\": \"gu+woR+x7PoRmaMqAP7oeOjK2V4U0NU8ofdacWZ34aY=\"\n\t\t\t\t\t},\n\t\t\t\t\t\"addr_list\": {\n\t\t\t\t\t\t\"@type\": \"adnl.addressList\",\n\t\t\t\t\t\t\"addrs\": [\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\"@type\": \"adnl.address.udp\",\n\t\t\t\t\t\t\t\t\"ip\": 1162057690,\n\t\t\t\t\t\t\t\t\"port\": 41578\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t],\n\t\t\t\t\t\t\"version\": 0,\n\t\t\t\t\t\t\"reinit_date\": 0,\n\t\t\t\t\t\t\"priority\": 0,\n\t\t\t\t\t\t\"expire_at\": 0\n\t\t\t\t\t},\n\t\t\t\t\t\"version\": -1,\n\t\t\t\t\t\"signature\": \"0PwDLXpN3IbRQuOTLkZBjkbT6+IkeUcvlhWrUY9us3IfSehmCfQjScR9mkVYsQ6cQHF+JeaFmqzV4GAiUcgjAg==\"\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"@type\": \"dht.node\",\n\t\t\t\t\t\"id\": {\n\t\t\t\t\t\t\"@type\": \"pub.ed25519\",\n\t\t\t\t\t\t\"key\": \"WC4BO1eZ916FnLBSKmt07Pn5NP4D3/1wary1VjaCLaY=\"\n\t\t\t\t\t},\n\t\t\t\t\t\"addr_list\": {\n\t\t\t\t\t\t\"@type\": \"adnl.addressList\",\n\t\t\t\t\t\t\"addrs\": [\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\"@type\": \"adnl.address.udp\",\n\t\t\t\t\t\t\t\t\"ip\": -1304477830,\n\t\t\t\t\t\t\t\t\"port\": 9670\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t],\n\t\t\t\t\t\t\"version\": 0,\n\t\t\t\t\t\t\"reinit_date\": 0,\n\t\t\t\t\t\t\"priority\": 0,\n\t\t\t\t\t\t\"expire_at\": 0\n\t\t\t\t\t},\n\t\t\t\t\t\"version\": -1,\n\t\t\t\t\t\"signature\": \"cvpzkGeuEuKV+d92qIVkln9ngm8qeDnmYtK5rq8uSet0392hAZcIv2IniDzTw0rN42NaOHL9A4KEelwKu1N2Ag==\"\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"@type\": \"dht.node\",\n\t\t\t\t\t\"id\": {\n\t\t\t\t\t\t\"@type\": \"pub.ed25519\",\n\t\t\t\t\t\t\"key\": \"nC8dcxV+EV2i0ARvub94IFJKKZUYACfY4xFj1NaG7Pw=\"\n\t\t\t\t\t},\n\t\t\t\t\t\"addr_list\": {\n\t\t\t\t\t\t\"@type\": \"adnl.addressList\",\n\t\t\t\t\t\t\"addrs\": [\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\"@type\": \"adnl.address.udp\",\n\t\t\t\t\t\t\t\t\"ip\": 1959453117,\n\t\t\t\t\t\t\t\t\"port\": 63625\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t],\n\t\t\t\t\t\t\"version\": 0,\n\t\t\t\t\t\t\"reinit_date\": 0,\n\t\t\t\t\t\t\"priority\": 0,\n\t\t\t\t\t\t\"expire_at\": 0\n\t\t\t\t\t},\n\t\t\t\t\t\"version\": -1,\n\t\t\t\t\t\"signature\": \"AHF6joNvQhyFFE0itV4OMA9n3Q8CEHVKapCLqazP7QJ4arsn4pdVkRYiGFEyQkngx+cm8izU4gB0JIaxF6PiBg==\"\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"@type\": \"dht.node\",\n\t\t\t\t\t\"id\": {\n\t\t\t\t\t\t\"@type\": \"pub.ed25519\",\n\t\t\t\t\t\t\"key\": \"dqsRZLzTg/P7uxUlQpgl4VyTBNYBRMc4js3mnRiolBk=\"\n\t\t\t\t\t},\n\t\t\t\t\t\"addr_list\": {\n\t\t\t\t\t\t\"@type\": \"adnl.addressList\",\n\t\t\t\t\t\t\"addrs\": [\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\"@type\": \"adnl.address.udp\",\n\t\t\t\t\t\t\t\t\"ip\": -809760973,\n\t\t\t\t\t\t\t\t\"port\": 40398\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t],\n\t\t\t\t\t\t\"version\": 0,\n\t\t\t\t\t\t\"reinit_date\": 0,\n\t\t\t\t\t\t\"priority\": 0,\n\t\t\t\t\t\t\"expire_at\": 0\n\t\t\t\t\t},\n\t\t\t\t\t\"version\": -1,\n\t\t\t\t\t\"signature\": \"mJxLrAv5RamN5B9mDz6MhQwFjF92D3drJ5efOSZryDaazil0AR4bRHh4vxzZlYiPhi/X/NyG6WwNvKBz+1ntBw==\"\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"@type\": \"dht.node\",\n\t\t\t\t\t\"id\": {\n\t\t\t\t\t\t\"@type\": \"pub.ed25519\",\n\t\t\t\t\t\t\"key\": \"fO6cFYRCRrD+yQzOJdHcNWpRFwu+qLhQnddLq0gGbTs=\"\n\t\t\t\t\t},\n\t\t\t\t\t\"addr_list\": {\n\t\t\t\t\t\t\"@type\": \"adnl.addressList\",\n\t\t\t\t\t\t\"addrs\": [\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\"@type\": \"adnl.address.udp\",\n\t\t\t\t\t\t\t\t\"ip\": 1097633201,\n\t\t\t\t\t\t\t\t\"port\": 7201\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t],\n\t\t\t\t\t\t\"version\": 0,\n\t\t\t\t\t\t\"reinit_date\": 0,\n\t\t\t\t\t\t\"priority\": 0,\n\t\t\t\t\t\t\"expire_at\": 0\n\t\t\t\t\t},\n\t\t\t\t\t\"version\": -1,\n\t\t\t\t\t\"signature\": \"o/rhtiUL3rvA08TKBcCn0DCiSjsNQdAv41aw7VVUig7ubaqJzYMv1cW3qMjxvsXn1BOugIheJm7voA1/brbtCg==\"\n\t\t\t\t}\n\t\t\t],\n\t\t\t\"@type\": \"dht.nodes\"\n\t\t},\n\t\t\"@type\": \"dht.config.global\"\n\t},\n\t\"@type\": \"config.global\",\n\t\"validator\": {\n\t\t\"zero_state\": {\n\t\t\t\"file_hash\": \"Z+IKwYS54DmmJmesw/nAD5DzWadnOCMzee+kdgSYDOg=\",\n\t\t\t\"seqno\": 0,\n\t\t\t\"root_hash\": \"gj+B8wb/AmlPk1z1AhVI484rhrUpgSr2oSFIh56VoSg=\",\n\t\t\t\"workchain\": -1,\n\t\t\t\"shard\": -9223372036854775808\n\t\t},\n\t\t\"@type\": \"validator.config.global\",\n\t\t\"init_block\": {\n\t\t\t\"workchain\": -1,\n\t\t\t\"shard\": -9223372036854775808,\n\t\t\t\"seqno\": 17908219,\n\t\t\t\"root_hash\": \"y6qWqhCnLgzWHjUFmXysaiOljuK5xVoCRMLzUwGInVM=\",\n\t\t\t\"file_hash\": \"Y/GziXxwuYte0AM4WT7tTWsCx+6rcfLpGmRaEQwhUKI=\"\n\t\t},\n\t\t\"hardforks\": [\n\t\t\t{\n\t\t\t\t\"file_hash\": \"jF3RTD+OyOoP+OI9oIjdV6M8EaOh9E+8+c3m5JkPYdg=\",\n\t\t\t\t\"seqno\": 5141579,\n\t\t\t\t\"root_hash\": \"6JSqIYIkW7y8IorxfbQBoXiuY3kXjcoYgQOxTJpjXXA=\",\n\t\t\t\t\"workchain\": -1,\n\t\t\t\t\"shard\": -9223372036854775808\n\t\t\t},\n\t\t\t{\n\t\t\t\t\"file_hash\": \"WrNoMrn5UIVPDV/ug/VPjYatvde8TPvz5v1VYHCLPh8=\",\n\t\t\t\t\"seqno\": 5172980,\n\t\t\t\t\"root_hash\": \"054VCNNtUEwYGoRe1zjH+9b1q21/MeM+3fOo76Vcjes=\",\n\t\t\t\t\"workchain\": -1,\n\t\t\t\t\"shard\": -9223372036854775808\n\t\t\t},\n\t\t\t{\n\t\t\t\t\"file_hash\": \"xRaxgUwgTXYFb16YnR+Q+VVsczLl6jmYwvzhQ/ncrh4=\",\n\t\t\t\t\"seqno\": 5176527,\n\t\t\t\t\"root_hash\": \"SoPLqMe9Dz26YJPOGDOHApTSe5i0kXFtRmRh/zPMGuI=\",\n\t\t\t\t\"workchain\": -1,\n\t\t\t\t\"shard\": -9223372036854775808\n\t\t\t}\n\t\t]\n\t}\n}\n"); + auto global_conf_data_R = td::read_file(global_config_); + if (global_conf_data_R.is_error()) { + LOG(FATAL) << global_conf_data_R.move_as_error_prefix("failed to read global config: "); + return; + } + auto tunnel_conf_data_R = td::read_file(tunnel_config_); + if (tunnel_conf_data_R.is_error()) { + LOG(FATAL) << tunnel_conf_data_R.move_as_error_prefix("failed to read tunnel config: "); + return; + } - LOG(INFO) << "INIT SERVER TUNNEL..."; - // TODO: pass port_ - auto res = PrepareTunnel(&on_recv_batch, callback_.release(), const_cast(cfg.data()), cfg.size(), const_cast(netCfg.data()), netCfg.size()); - LOG(INFO) << "INIT SERVER TUNNEL DONE"; + auto global_cfg = global_conf_data_R.move_as_ok(); + auto tunnel_cfg = tunnel_conf_data_R.move_as_ok(); + + LOG(INFO) << "Initializing ADNL Tunnel..."; + auto res = PrepareTunnel(&on_recv_batch, &on_reinit, callback_.get(), callback_.get(), const_cast(tunnel_cfg.data()), tunnel_cfg.size(), global_cfg.data(), global_cfg.size()); + if (!res.index) { + LOG(FATAL) << "ADNL Tunnel initialization failed"; + } tunnel_index_ = res.index; + LOG(INFO) << "ADNL Tunnel Initialized"; td:IPAddress ip; ip.init_ipv4_port(td::IPAddress::ipv4_to_str(res.ip), static_cast(res.port)).ensure(); on_ready_.set_value(std::move(ip)); - alarm_timestamp() = td::Timestamp::in(0.05); + alarm_timestamp() = td::Timestamp::in(0.02); } -void UdpServerTunnelImpl::on_recv_batch(void *next, char *data, size_t num) { +void UdpServerTunnelImpl::on_recv_batch(void *next, uint8_t *data, size_t num) { for (size_t i = 0; i < num; i++) { - UdpMessage msg; + UdpMessage msg{}; msg.address.init_sockaddr(reinterpret_cast(data)); - const uint16_t len = (static_cast(data[16]) << 8) + data[17]; - msg.data = BufferSlice(data+18, len); + const uint16_t len = (static_cast(data[16]) << 8) + static_cast(data[17]); + msg.data = BufferSlice(reinterpret_cast(data + 18), len); data += 18+len; // both init_sockaddr and BufferSlice doing memcpy so it is safe - static_cast(next)->on_udp_message(std::move(msg)); + static_cast(next)->on_udp_message(std::move(msg)); } } -td::actor::ActorOwn UdpServerTunnelImpl::create(td::Slice name, int32 port, - std::unique_ptr callback, - td::Promise on_ready) { - return td::actor::create_actor( - actor::ActorOptions().with_name(name).with_poll(!td::Poll::is_edge_triggered()), port, std::move(callback), std::move(on_ready)); +void UdpServerTunnelImpl::on_reinit(void *next, sockaddr *addr) { + td::IPAddress ip; + ip.init_sockaddr(addr); + + static_cast(next)->on_in_addr_update(std::move(ip)); } -UdpServerTunnelImpl::UdpServerTunnelImpl(int32 port, std::unique_ptr callback, td::Promise on_ready): port_(port), callback_(std::move(callback)), on_ready_(std::move(on_ready)) { +td::actor::ActorOwn UdpServerTunnelImpl::create(td::Slice name, std::string global_config, std::string tunnel_config, + std::unique_ptr callback, + td::Promise on_ready) { + return td::actor::create_actor( + actor::ActorOptions().with_name(name).with_poll(!td::Poll::is_edge_triggered()), global_config, tunnel_config, std::move(callback), std::move(on_ready)); +} + +UdpServerTunnelImpl::UdpServerTunnelImpl(std::string global_config, std::string tunnel_config, std::unique_ptr callback, td::Promise on_ready): on_ready_(std::move(on_ready)) + , global_config_(global_config) + , tunnel_config_(tunnel_config) + , callback_(std::move(callback)) { } class UdpServerImpl : public UdpServer { @@ -511,10 +537,10 @@ Result> UdpServer::create(td::Slice name, int32 port, return detail::UdpServerImpl::create(name, std::move(fd), std::move(callback)); } -Result> UdpServer::create_via_tunnel(td::Slice name, int32 port, - std::unique_ptr callback, +Result> UdpServer::create_via_tunnel(td::Slice name, std::string global_config, std::string tunnel_config, + std::unique_ptr callback, td::Promise on_ready) { - return detail::UdpServerTunnelImpl::create(name, port, std::move(callback), std::move(on_ready)); + return detail::UdpServerTunnelImpl::create(name, global_config, tunnel_config, std::move(callback), std::move(on_ready)); } Result> UdpServer::create_via_tcp(td::Slice name, int32 port, diff --git a/tdnet/td/net/UdpServer.h b/tdnet/td/net/UdpServer.h index 4219f4a1..e6de2dcc 100644 --- a/tdnet/td/net/UdpServer.h +++ b/tdnet/td/net/UdpServer.h @@ -28,17 +28,21 @@ namespace td { class UdpServer : public td::actor::Actor { public: class Callback { - public: + public: virtual ~Callback() = default; virtual void on_udp_message(td::UdpMessage udp_message) = 0; }; + class TunnelCallback : public Callback { + public: + virtual void on_in_addr_update(td::IPAddress ip) = 0; + }; virtual void send(td::UdpMessage &&message) = 0; static Result> create(td::Slice name, int32 port, std::unique_ptr callback); static Result> create_via_tcp(td::Slice name, int32 port, std::unique_ptr callback); - static Result> create_via_tunnel(td::Slice name, int32 port, - std::unique_ptr callback, + static Result> create_via_tunnel(td::Slice name, std::string global_config, std::string tunnel_config, + std::unique_ptr callback, td::Promise on_ready); }; diff --git a/tdnet/td/net/tunnel/libtunnel.h b/tdnet/td/net/tunnel/libtunnel.h index 3d48b01b..30e377f0 100644 --- a/tdnet/td/net/tunnel/libtunnel.h +++ b/tdnet/td/net/tunnel/libtunnel.h @@ -21,6 +21,9 @@ typedef struct { const char *p; ptrdiff_t n; } _GoString_; #line 3 "lib.go" +#include +#include + typedef struct { size_t index; int ip; @@ -28,14 +31,18 @@ typedef struct { } Tunnel; // next - is pointer to class instance or callback to call method from node code -typedef void (*RecvCallback)(void* next, char * data, size_t num); +typedef void (*RecvCallback)(void* next, uint8_t* data, size_t num); -typedef void (*PullSendCallback)(void* next, char * data, size_t num); +typedef void (*ReinitCallback)(void* next, struct sockaddr* data); // we need it because we cannot call C func by pointer directly from go static inline void on_recv_batch_ready(RecvCallback cb, void* next, void* data, size_t num) { - cb(next, (char*)data, num); + cb(next, (uint8_t*)data, num); +} + +static inline void on_reinit(ReinitCallback cb, void* next, void* data) { + cb(next, (struct sockaddr*)data); } #line 1 "cgo-generated-wrapper" @@ -96,8 +103,8 @@ extern "C" { //goland:noinspection ALL -extern Tunnel PrepareTunnel(RecvCallback onRecv, void* next, char* configJson, int configJsonLen, char* networkConfigJson, int networkConfigJsonLen); -extern int WriteTunnel(size_t tunIdx, char* data, size_t num); +extern Tunnel PrepareTunnel(RecvCallback onRecv, ReinitCallback onReinit, void* nextOnRecv, void* nextOnReinit, char* configJson, int configJsonLen, char* networkConfigJson, int networkConfigJsonLen); +extern int WriteTunnel(size_t tunIdx, uint8_t* data, size_t num); #ifdef __cplusplus } diff --git a/tl/generate/scheme/ton_api.tl b/tl/generate/scheme/ton_api.tl index 75e5c298..cfc9f3a1 100644 --- a/tl/generate/scheme/ton_api.tl +++ b/tl/generate/scheme/ton_api.tl @@ -648,7 +648,7 @@ engine.validator.fullNodeMaster port:int adnl:int256 = engine.validator.FullNode engine.validator.fullNodeSlave ip:int port:int adnl:PublicKey = engine.validator.FullNodeSlave; engine.validator.fullNodeConfig ext_messages_broadcast_disabled:Bool = engine.validator.FullNodeConfig; engine.validator.extraConfig state_serializer_enabled:Bool = engine.validator.ExtraConfig; -engine.validator.config out_port:int tunnel_enabled:int addrs:(vector engine.Addr) adnl:(vector engine.adnl) +engine.validator.config out_port:int addrs:(vector engine.Addr) adnl:(vector engine.adnl) dht:(vector engine.dht) validators:(vector engine.validator) fullnode:int256 fullnodeslaves:(vector engine.validator.fullNodeSlave) fullnodemasters:(vector engine.validator.fullNodeMaster) diff --git a/tl/generate/scheme/ton_api.tlo b/tl/generate/scheme/ton_api.tlo index a6d86030aa00f69ed45f1a416dd3d7fe78573b78..96ecb7751b1ad3a31830cba56037d0037988cde3 100644 GIT binary patch delta 58 zcmeyffbGfxwhb3VS)``>AKiRKbV)y$HMwS~1Sd%7<}o23zUhTQj5?b?E^TIlD63e( G@&W+;{27%1 delta 82 zcmcbzfbGu$whb3VS@cz&eb{_ObV)xeh$TKbafJv^T4p+kbMu&x5C3$>Xhv;*zLL_s fywsfd)V#!`oYa)b`yHe(config.out_port_); - tunnel_enabled = true; //static_cast(config.tunnel_enabled_); if (!out_port) { out_port = 3278; } @@ -279,7 +278,7 @@ ton::tl_object_ptr Config::tl() const { } return ton::create_tl_object( - out_port, 0, std::move(addrs_vec), std::move(adnl_vec), std::move(dht_vec), std::move(val_vec), + out_port, std::move(addrs_vec), std::move(adnl_vec), std::move(dht_vec), std::move(val_vec), full_node.tl(), std::move(full_node_slaves_vec), std::move(full_node_masters_vec), std::move(full_node_config_obj), std::move(extra_config_obj), std::move(liteserver_vec), std::move(control_vec), std::move(shards_vec), std::move(gc_vec)); @@ -1277,6 +1276,9 @@ void ValidatorEngine::set_local_config(std::string str) { void ValidatorEngine::set_global_config(std::string str) { global_config_ = str; } +void ValidatorEngine::set_tunnel_config(std::string str) { + tunnel_config_ = str; +} void ValidatorEngine::set_db_root(std::string db_root) { db_root_ = db_root; } @@ -1849,7 +1851,7 @@ void ValidatorEngine::start_adnl() { adnl_ = ton::adnl::Adnl::create(db_root_, keyring_.get()); td::actor::send_closure(adnl_, &ton::adnl::Adnl::register_network_manager, adnl_network_manager_.get()); - if (config_.tunnel_enabled) { + if (!tunnel_config_.empty()) { auto on_tunnel_ready = td::PromiseCreator::lambda([SelfId = actor_id(this), this](td::Result R) { R.ensure(); auto addr = R.move_as_ok(); @@ -1870,14 +1872,41 @@ void ValidatorEngine::start_adnl() { td::actor::send_closure(SelfId, &ValidatorEngine::started_adnl); }); - ton::adnl::AdnlCategoryMask cat_mask; - cat_mask[0] = true; - cat_mask[1] = true; - cat_mask[2] = true; - cat_mask[3] = true; + class Handler : public ton::adnl::AdnlNetworkManager::TunnelEventsHandler { + public: + Handler(ValidatorEngine *scheduler) + : validator_engine_(scheduler) { + } - td::actor::send_closure(adnl_network_manager_, &ton::adnl::AdnlNetworkManager::add_tunnel, 3433, - std::move(cat_mask), 0, std::move(on_tunnel_ready)); + private: + ValidatorEngine *validator_engine_; + void on_in_addr_update(td::IPAddress ip) override { + validator_engine_->scheduler_->run_in_context_external([&] { + LOG(INFO) << "[EVENT] Tunnel reinitialized, addr: " << ip; + + validator_engine_->addr_lists_.clear(); + validator_engine_->add_addr(Config::Addr{}, Config::AddrCats{ + .in_addr = ip, + .is_tunnel = true, + .cats = {0, 1, 2, 3}, + }); + + for (auto &adnl : validator_engine_->config_.adnl_ids) { + validator_engine_->add_adnl(adnl.first, adnl.second); + } + }); + } + }; + + td::actor::send_closure(adnl_network_manager_, &ton::adnl::AdnlNetworkManager::install_tunnel_events_handler, std::make_unique(this)); + + ton::adnl::AdnlCategoryMask cat_mask; + for (int i = 0; i <= 3; i++) { + cat_mask[i] = true; + } + + td::actor::send_closure(adnl_network_manager_, &ton::adnl::AdnlNetworkManager::add_tunnel, global_config_, tunnel_config_, + std::move(cat_mask), 0, std::move(on_tunnel_ready), scheduler_); return; } @@ -4342,6 +4371,10 @@ int main(int argc, char *argv[]) { acts.push_back( [&x, fname = fname.str()]() { td::actor::send_closure(x, &ValidatorEngine::set_local_config, fname); }); }); + p.add_option('\0', "tunnel-config", "file to read tunnel config", [&](td::Slice fname) { + acts.push_back( + [&x, fname = fname.str()]() { td::actor::send_closure(x, &ValidatorEngine::set_tunnel_config, fname); }); + }); p.add_checked_option('I', "ip", "ip:port of instance", [&](td::Slice arg) { td::IPAddress addr; TRY_STATUS(addr.init_host_port(arg.str())); @@ -4607,7 +4640,7 @@ int main(int argc, char *argv[]) { scheduler.run_in_context([&] { vm::init_vm().ensure(); - x = td::actor::create_actor("validator-engine"); + x = td::actor::create_actor("validator-engine", &scheduler); for (auto &act : acts) { act(); } diff --git a/validator-engine/validator-engine.hpp b/validator-engine/validator-engine.hpp index 3b79564d..eb52006f 100644 --- a/validator-engine/validator-engine.hpp +++ b/validator-engine/validator-engine.hpp @@ -79,7 +79,6 @@ struct Config { std::map keys_refcnt; td::uint16 out_port; - bool tunnel_enabled; std::map addrs; std::map adnl_ids; std::set dht_ids; @@ -142,6 +141,8 @@ struct Config { class ValidatorEngine : public td::actor::Actor { private: + td::actor::Scheduler* scheduler_; + td::actor::ActorOwn keyring_; td::actor::ActorOwn adnl_network_manager_; td::actor::ActorOwn adnl_; @@ -158,6 +159,7 @@ class ValidatorEngine : public td::actor::Actor { std::string local_config_ = ""; std::string global_config_ = "ton-global.config"; + std::string tunnel_config_ = ""; std::string config_file_; std::string temp_config_file() const { return config_file_ + ".tmp"; @@ -247,6 +249,7 @@ class ValidatorEngine : public td::actor::Actor { } void set_local_config(std::string str); void set_global_config(std::string str); + void set_tunnel_config(std::string str); void set_fift_dir(std::string str) { fift_dir_ = str; } @@ -329,7 +332,7 @@ class ValidatorEngine : public td::actor::Actor { } void start_up() override; - ValidatorEngine() { + explicit ValidatorEngine(td::actor::Scheduler* scheduler): scheduler_(scheduler) { } // load config From 723de3cbad2c7f971b79153d05632a1a4b0012da Mon Sep 17 00:00:00 2001 From: Oleg Baranov Date: Tue, 25 Feb 2025 17:26:39 +0400 Subject: [PATCH 06/13] Fixed dht compile --- dht-server/dht-server.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dht-server/dht-server.cpp b/dht-server/dht-server.cpp index d7bb84e0..fa9fad13 100644 --- a/dht-server/dht-server.cpp +++ b/dht-server/dht-server.cpp @@ -169,7 +169,7 @@ ton::tl_object_ptr Config::tl() const { gc_vec->ids_.push_back(id.tl()); } return ton::create_tl_object( - out_port, 0, std::move(addrs_vec), std::move(adnl_vec), std::move(dht_vec), std::move(val_vec), + out_port, std::move(addrs_vec), std::move(adnl_vec), std::move(dht_vec), std::move(val_vec), ton::PublicKeyHash::zero().tl(), std::move(full_node_slaves_vec), std::move(full_node_masters_vec), nullptr, nullptr, std::move(liteserver_vec), std::move(control_vec), std::move(shard_vec), std::move(gc_vec)); } From 9ef4d929dfa767b7b0044bbc4b113a78616b6cfb Mon Sep 17 00:00:00 2001 From: Oleg Baranov Date: Tue, 25 Feb 2025 21:51:26 +0400 Subject: [PATCH 07/13] Added udp msg size check --- tdnet/td/net/UdpServer.cpp | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/tdnet/td/net/UdpServer.cpp b/tdnet/td/net/UdpServer.cpp index c90a2ca2..8cdb420a 100644 --- a/tdnet/td/net/UdpServer.cpp +++ b/tdnet/td/net/UdpServer.cpp @@ -46,7 +46,7 @@ class UdpServerTunnelImpl : public UdpServer { private: td::Promise on_ready_; - uint8_t out_buf_[(16+2+1500)*300]; + uint8_t out_buf_[(16+2+1500)*100]; size_t out_buf_offset_ = 0; size_t out_buf_msg_num_ = 0; size_t tunnel_index_; @@ -75,13 +75,17 @@ void UdpServerTunnelImpl::send(td::UdpMessage &&message) { out_buf_[out_buf_offset_] = static_cast(sz >> 8); out_buf_[out_buf_offset_ + 1] = static_cast(sz & 0xff); + if (sz > 1500) { + LOG(WARNING) << "udp message is too big, dropping"; + return; + } + memcpy(out_buf_ + out_buf_offset_ + 2, message.data.data(), sz); out_buf_offset_ += 2 + sz; out_buf_msg_num_++; - if (out_buf_msg_num_ >= 100) { - td::Timer timer; + if (out_buf_msg_num_ == 100) { WriteTunnel(tunnel_index_, out_buf_, out_buf_msg_num_); out_buf_offset_ = 0; From 2dea1c3b1124204483d280b5475f05271a5d1685 Mon Sep 17 00:00:00 2001 From: Oleg Baranov Date: Tue, 25 Feb 2025 22:51:14 +0400 Subject: [PATCH 08/13] Disable tunnel in cmake by default --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index f3d34b86..9a9bb13a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -105,7 +105,7 @@ option(TON_USE_ASAN "Use \"ON\" to enable AddressSanitizer." OFF) option(TON_USE_TSAN "Use \"ON\" to enable ThreadSanitizer." OFF) option(TON_USE_UBSAN "Use \"ON\" to enable UndefinedBehaviorSanitizer." OFF) set(TON_ARCH "native" CACHE STRING "Architecture, will be passed to -march=") -option(TON_USE_GO_TUNNEL "Use \"ON\" to enable ADNL Tunnel over shared Go library." ON) +option(TON_USE_GO_TUNNEL "Use \"ON\" to enable ADNL Tunnel over shared Go library." OFF) if (TON_USE_GO_TUNNEL) set(TUNNEL_GO_LIB_PATH "${CMAKE_CURRENT_SOURCE_DIR}/libtunnel.a") From 6382cd3962907bf73fc65560bc6ec6d196c5760f Mon Sep 17 00:00:00 2001 From: Oleg Baranov Date: Wed, 26 Feb 2025 10:43:06 +0400 Subject: [PATCH 09/13] Smaller batch for tunnel write to debug --- tdnet/td/net/UdpServer.cpp | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/tdnet/td/net/UdpServer.cpp b/tdnet/td/net/UdpServer.cpp index 8cdb420a..d2991982 100644 --- a/tdnet/td/net/UdpServer.cpp +++ b/tdnet/td/net/UdpServer.cpp @@ -85,7 +85,7 @@ void UdpServerTunnelImpl::send(td::UdpMessage &&message) { out_buf_msg_num_++; - if (out_buf_msg_num_ == 100) { + if (out_buf_msg_num_ == 3) { WriteTunnel(tunnel_index_, out_buf_, out_buf_msg_num_); out_buf_offset_ = 0; @@ -95,15 +95,14 @@ void UdpServerTunnelImpl::send(td::UdpMessage &&message) { } void UdpServerTunnelImpl::alarm() { - auto now = Time::now(); - if (out_buf_msg_num_ > 0 && now-last_batch_at_ >= 0.02) { + if (out_buf_msg_num_ > 0 && Time::now()-last_batch_at_ >= 0.02) { td::Timer timer; WriteTunnel(tunnel_index_, out_buf_, out_buf_msg_num_); // LOG(ERROR) << "Sending messages from alarm " << out_buf_msg_num_ << " | " << timer.elapsed(); out_buf_offset_ = 0; out_buf_msg_num_ = 0; - last_batch_at_ = now; + last_batch_at_ = Time::now(); } alarm_timestamp() = td::Timestamp::in(0.02); From 73e01f63612a4e7da66c9851a2ffcaa3eddad005 Mon Sep 17 00:00:00 2001 From: Oleg Baranov Date: Wed, 26 Feb 2025 14:39:18 +0400 Subject: [PATCH 10/13] Bigger batch for tunnel write to debug --- README.md | 16 ++++++++++++++++ tdnet/td/net/UdpServer.cpp | 8 +++++--- 2 files changed, 21 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 897ba809..32f0f4fe 100644 --- a/README.md +++ b/README.md @@ -149,3 +149,19 @@ Linux and MacOS binaries are available for both x86-64 and arm64 architectures. ## Running tests Tests are executed by running `ctest` in the build directory. See `doc/Tests.md` for more information. + +## Using ADNL tunnel + +### Before node compilation +1. Clone https://github.com/ton-blockchain/adnl-tunnel and install golang 1.23 or newer + * `cd adnl-tunnel` + * `make library` + * It will build `libtunnel.a` +2. Copy `libtunnel.a` to ton src directory root (usually `/usr/src/ton`) +3. On the first step of ton node compilation run cmake with option `-DTON_USE_GO_TUNNEL=ON` to enable tunnel. +4. Build ton node as usual. + +### Before startup +1. Create `tunnel-config.json` in any place. +2. Fill it with desired tunnel configuration and wallet keys. See example. +3Add `--tunnel-config /path/to/tunnel-config.json` argument to validator-engine startup command. \ No newline at end of file diff --git a/tdnet/td/net/UdpServer.cpp b/tdnet/td/net/UdpServer.cpp index d2991982..43c44f0f 100644 --- a/tdnet/td/net/UdpServer.cpp +++ b/tdnet/td/net/UdpServer.cpp @@ -46,7 +46,7 @@ class UdpServerTunnelImpl : public UdpServer { private: td::Promise on_ready_; - uint8_t out_buf_[(16+2+1500)*100]; + uint8_t out_buf_[(16+2+1500)*300]; size_t out_buf_offset_ = 0; size_t out_buf_msg_num_ = 0; size_t tunnel_index_; @@ -85,8 +85,10 @@ void UdpServerTunnelImpl::send(td::UdpMessage &&message) { out_buf_msg_num_++; - if (out_buf_msg_num_ == 3) { + if (out_buf_msg_num_ == 300) { + td::Timer timer; WriteTunnel(tunnel_index_, out_buf_, out_buf_msg_num_); + LOG(ERROR) << "Sending messages by num " << out_buf_msg_num_ << " | " << timer.elapsed(); out_buf_offset_ = 0; out_buf_msg_num_ = 0; @@ -98,7 +100,7 @@ void UdpServerTunnelImpl::alarm() { if (out_buf_msg_num_ > 0 && Time::now()-last_batch_at_ >= 0.02) { td::Timer timer; WriteTunnel(tunnel_index_, out_buf_, out_buf_msg_num_); - // LOG(ERROR) << "Sending messages from alarm " << out_buf_msg_num_ << " | " << timer.elapsed(); + LOG(ERROR) << "Sending messages from alarm " << out_buf_msg_num_ << " | " << timer.elapsed(); out_buf_offset_ = 0; out_buf_msg_num_ = 0; From eb479c81e0529fcc9a91b96a2735d6997ccda48b Mon Sep 17 00:00:00 2001 From: Oleg Baranov Date: Wed, 26 Feb 2025 21:45:28 +0400 Subject: [PATCH 11/13] Tunnel server small refactor --- tdnet/td/net/UdpServer.cpp | 28 +++++++++++++++------------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/tdnet/td/net/UdpServer.cpp b/tdnet/td/net/UdpServer.cpp index 43c44f0f..9e17d35e 100644 --- a/tdnet/td/net/UdpServer.cpp +++ b/tdnet/td/net/UdpServer.cpp @@ -33,6 +33,10 @@ int VERBOSITY_NAME(udp_server) = VERBOSITY_NAME(DEBUG) + 10; } namespace detail { +#define TUNNEL_BUFFER_SZ_PACKETS 100 +#define TUNNEL_MAX_PACKET_MTU 1500 +#define TUNNEL_ALARM_EVERY 0.01 + class UdpServerTunnelImpl : public UdpServer { public: void start_up() override; @@ -46,7 +50,7 @@ class UdpServerTunnelImpl : public UdpServer { private: td::Promise on_ready_; - uint8_t out_buf_[(16+2+1500)*300]; + uint8_t out_buf_[(sizeof(sockaddr)+2+TUNNEL_MAX_PACKET_MTU)*TUNNEL_BUFFER_SZ_PACKETS]; size_t out_buf_offset_ = 0; size_t out_buf_msg_num_ = 0; size_t tunnel_index_; @@ -64,8 +68,8 @@ private: }; void UdpServerTunnelImpl::send(td::UdpMessage &&message) { - auto sock = message.address.get_sockaddr(); - auto sz = message.data.size(); + const auto sock = message.address.get_sockaddr(); + const auto sz = message.data.size(); // ip+port memcpy(out_buf_ + out_buf_offset_, sock, sizeof(sockaddr)); @@ -75,7 +79,7 @@ void UdpServerTunnelImpl::send(td::UdpMessage &&message) { out_buf_[out_buf_offset_] = static_cast(sz >> 8); out_buf_[out_buf_offset_ + 1] = static_cast(sz & 0xff); - if (sz > 1500) { + if (sz > TUNNEL_MAX_PACKET_MTU) { LOG(WARNING) << "udp message is too big, dropping"; return; } @@ -85,10 +89,9 @@ void UdpServerTunnelImpl::send(td::UdpMessage &&message) { out_buf_msg_num_++; - if (out_buf_msg_num_ == 300) { - td::Timer timer; + if (out_buf_msg_num_ == TUNNEL_BUFFER_SZ_PACKETS) { WriteTunnel(tunnel_index_, out_buf_, out_buf_msg_num_); - LOG(ERROR) << "Sending messages by num " << out_buf_msg_num_ << " | " << timer.elapsed(); + LOG(DEBUG) << "Sending messages by fulfillment " << TUNNEL_BUFFER_SZ_PACKETS; out_buf_offset_ = 0; out_buf_msg_num_ = 0; @@ -97,17 +100,16 @@ void UdpServerTunnelImpl::send(td::UdpMessage &&message) { } void UdpServerTunnelImpl::alarm() { - if (out_buf_msg_num_ > 0 && Time::now()-last_batch_at_ >= 0.02) { - td::Timer timer; + if (out_buf_msg_num_ > 0 && Time::now()-last_batch_at_ >= TUNNEL_ALARM_EVERY) { WriteTunnel(tunnel_index_, out_buf_, out_buf_msg_num_); - LOG(ERROR) << "Sending messages from alarm " << out_buf_msg_num_ << " | " << timer.elapsed(); + LOG(DEBUG) << "Sending messages by alarm " << out_buf_msg_num_; out_buf_offset_ = 0; out_buf_msg_num_ = 0; last_batch_at_ = Time::now(); } - alarm_timestamp() = td::Timestamp::in(0.02); + alarm_timestamp() = td::Timestamp::in(TUNNEL_ALARM_EVERY); } void UdpServerTunnelImpl::start_up() { @@ -127,7 +129,7 @@ void UdpServerTunnelImpl::start_up() { auto tunnel_cfg = tunnel_conf_data_R.move_as_ok(); LOG(INFO) << "Initializing ADNL Tunnel..."; - auto res = PrepareTunnel(&on_recv_batch, &on_reinit, callback_.get(), callback_.get(), const_cast(tunnel_cfg.data()), tunnel_cfg.size(), global_cfg.data(), global_cfg.size()); + const auto res = PrepareTunnel(&on_recv_batch, &on_reinit, callback_.get(), callback_.get(), const_cast(tunnel_cfg.data()), tunnel_cfg.size(), global_cfg.data(), global_cfg.size()); if (!res.index) { LOG(FATAL) << "ADNL Tunnel initialization failed"; } @@ -138,7 +140,7 @@ void UdpServerTunnelImpl::start_up() { ip.init_ipv4_port(td::IPAddress::ipv4_to_str(res.ip), static_cast(res.port)).ensure(); on_ready_.set_value(std::move(ip)); - alarm_timestamp() = td::Timestamp::in(0.02); + alarm_timestamp() = td::Timestamp::in(TUNNEL_ALARM_EVERY); } void UdpServerTunnelImpl::on_recv_batch(void *next, uint8_t *data, size_t num) { From be71eedc4b8b204a58ea69b91a5dbd2573cca74b Mon Sep 17 00:00:00 2001 From: Oleg Baranov Date: Thu, 27 Feb 2025 11:04:34 +0400 Subject: [PATCH 12/13] Tunnel config loading moved to lib part --- tdnet/td/net/UdpServer.cpp | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/tdnet/td/net/UdpServer.cpp b/tdnet/td/net/UdpServer.cpp index 9e17d35e..f75dd85b 100644 --- a/tdnet/td/net/UdpServer.cpp +++ b/tdnet/td/net/UdpServer.cpp @@ -119,19 +119,13 @@ void UdpServerTunnelImpl::start_up() { return; } - auto tunnel_conf_data_R = td::read_file(tunnel_config_); - if (tunnel_conf_data_R.is_error()) { - LOG(FATAL) << tunnel_conf_data_R.move_as_error_prefix("failed to read tunnel config: "); - return; - } - auto global_cfg = global_conf_data_R.move_as_ok(); - auto tunnel_cfg = tunnel_conf_data_R.move_as_ok(); LOG(INFO) << "Initializing ADNL Tunnel..."; - const auto res = PrepareTunnel(&on_recv_batch, &on_reinit, callback_.get(), callback_.get(), const_cast(tunnel_cfg.data()), tunnel_cfg.size(), global_cfg.data(), global_cfg.size()); + const auto res = PrepareTunnel(&on_recv_batch, &on_reinit, callback_.get(), callback_.get(), tunnel_config_.data(), tunnel_config_.size(), global_cfg.data(), global_cfg.size()); if (!res.index) { - LOG(FATAL) << "ADNL Tunnel initialization failed"; + // the reason will be displayed in logs from lib part + exit(1); } tunnel_index_ = res.index; LOG(INFO) << "ADNL Tunnel Initialized"; From 0c5eff2a98d412e835e41d02f3198314b489ff5e Mon Sep 17 00:00:00 2001 From: Oleg Baranov Date: Mon, 3 Mar 2025 14:36:52 +0400 Subject: [PATCH 13/13] CMake flag define for adnl tunnel --- CMakeLists.txt | 1 + README.md | 16 +++++++++------- tdnet/td/net/UdpServer.cpp | 10 ++++++++++ 3 files changed, 20 insertions(+), 7 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 9a9bb13a..9cb2b2b6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -115,6 +115,7 @@ if (TON_USE_GO_TUNNEL) add_library(tunnel STATIC IMPORTED) set_target_properties(tunnel PROPERTIES IMPORTED_LOCATION "${TUNNEL_GO_LIB_PATH}") set(TUNNEL_LIB_IF_USED "tunnel") + add_compile_definitions(TON_USE_GO_TUNNEL) else() message(FATAL_ERROR "Missing ADNL Tunnel library (Go), but enabled: ${TUNNEL_GO_LIB_PATH}") endif() diff --git a/README.md b/README.md index 32f0f4fe..8376f486 100644 --- a/README.md +++ b/README.md @@ -152,16 +152,18 @@ Tests are executed by running `ctest` in the build directory. See `doc/Tests.md` ## Using ADNL tunnel -### Before node compilation -1. Clone https://github.com/ton-blockchain/adnl-tunnel and install golang 1.23 or newer +### At node compilation +1. Clone https://github.com/ton-blockchain/adnl-tunnel and install golang 1.23.3 or newer * `cd adnl-tunnel` * `make library` * It will build `libtunnel.a` -2. Copy `libtunnel.a` to ton src directory root (usually `/usr/src/ton`) +2. Copy `libtunnel.a` to ton src directory root (usually `/usr/src/ton`). 3. On the first step of ton node compilation run cmake with option `-DTON_USE_GO_TUNNEL=ON` to enable tunnel. 4. Build ton node as usual. -### Before startup -1. Create `tunnel-config.json` in any place. -2. Fill it with desired tunnel configuration and wallet keys. See example. -3Add `--tunnel-config /path/to/tunnel-config.json` argument to validator-engine startup command. \ No newline at end of file +### At node startup +1. Run validator-engine with `--tunnel-config /path/to/tunnel-config.json` startup argument. +2. It will create example tunnel config file at specified path (`/path/to/tunnel-config.json`). +3. Fill it with desired tunnel configuration, enable payments and top up wallet address if needed. +4. Run validator-engine `--tunnel-config /path/to/tunnel-config.json` again, and follow instructions in console if any. +5. When setup is completed and node started, you can stop it and run in daemon mode as usual. \ No newline at end of file diff --git a/tdnet/td/net/UdpServer.cpp b/tdnet/td/net/UdpServer.cpp index f75dd85b..fdb94da7 100644 --- a/tdnet/td/net/UdpServer.cpp +++ b/tdnet/td/net/UdpServer.cpp @@ -20,7 +20,9 @@ #include "td/net/FdListener.h" #include "td/net/TcpListener.h" +#ifdef TON_USE_GO_TUNNEL #include "td/net/tunnel/libtunnel.h" +#endif #include "td/utils/BufferedFd.h" #include "td/utils/filesystem.h" @@ -90,8 +92,10 @@ void UdpServerTunnelImpl::send(td::UdpMessage &&message) { if (out_buf_msg_num_ == TUNNEL_BUFFER_SZ_PACKETS) { +#ifdef TON_USE_GO_TUNNEL WriteTunnel(tunnel_index_, out_buf_, out_buf_msg_num_); LOG(DEBUG) << "Sending messages by fulfillment " << TUNNEL_BUFFER_SZ_PACKETS; +#endif out_buf_offset_ = 0; out_buf_msg_num_ = 0; @@ -101,8 +105,10 @@ void UdpServerTunnelImpl::send(td::UdpMessage &&message) { void UdpServerTunnelImpl::alarm() { if (out_buf_msg_num_ > 0 && Time::now()-last_batch_at_ >= TUNNEL_ALARM_EVERY) { +#ifdef TON_USE_GO_TUNNEL WriteTunnel(tunnel_index_, out_buf_, out_buf_msg_num_); LOG(DEBUG) << "Sending messages by alarm " << out_buf_msg_num_; +#endif out_buf_offset_ = 0; out_buf_msg_num_ = 0; @@ -113,6 +119,7 @@ void UdpServerTunnelImpl::alarm() { } void UdpServerTunnelImpl::start_up() { +#ifdef TON_USE_GO_TUNNEL auto global_conf_data_R = td::read_file(global_config_); if (global_conf_data_R.is_error()) { LOG(FATAL) << global_conf_data_R.move_as_error_prefix("failed to read global config: "); @@ -135,6 +142,9 @@ void UdpServerTunnelImpl::start_up() { on_ready_.set_value(std::move(ip)); alarm_timestamp() = td::Timestamp::in(TUNNEL_ALARM_EVERY); +#else + LOG(FATAL) << "Tunnel was not enabled during node building, rebuild with cmake flag -DTON_USE_GO_TUNNEL=ON"; +#endif } void UdpServerTunnelImpl::on_recv_batch(void *next, uint8_t *data, size_t num) {