├── CMakeLists.txt ├── tests ├── CMakeLists.txt ├── test_main.cc ├── test_root_routing.cc ├── test_multi_routing.cc └── test_root_routing_manager.cc ├── xwrouter.xcodeproj ├── xcuserdata │ └── imac.xcuserdatad │ │ └── xcschemes │ │ └── xcschememanagement.plist └── project.pbxproj ├── demo ├── CMakeLists.txt ├── main.h ├── commands.h └── demo_routing.h ├── root ├── root_message_handler.h ├── root_routing_manager.h └── root_routing.h ├── register_message_handler.h ├── wrouter_utils ├── wrouter_base_routing.h └── wrouter_utils.h ├── src ├── register_message_handler.cc ├── root_message_handler.cc ├── rumor_message_handler.cc ├── small_net_cache.cc ├── xwrouter_handler.cc ├── register_routing_table.cc ├── xwrouter.cc ├── root_routing_manager.cc ├── multi_routing.cc ├── xwrouter_xip_handler.cc └── root_routing.cc ├── multi_routing ├── small_net_cache.h └── multi_routing.h ├── message_handler ├── rumor_message_handler.h ├── xwrouter_xip_handler.h ├── xwrouter_handler.h ├── xwrouter_xid_handler.h └── wrouter_message_handler.h ├── register_routing_table.h ├── README.md └── xwrouter.h /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.8) 2 | 3 | aux_source_directory(./src xwrouter_src) 4 | add_library(xwrouter STATIC ${xwrouter_src}) 5 | 6 | add_dependencies(xwrouter xkad) 7 | 8 | target_link_libraries(xwrouter PRIVATE xkad xgossip cpp_redis tacopie) 9 | if(CMAKE_SYSTEM_NAME STREQUAL "Linux") 10 | if (XENABLE_CODE_COVERAGE) 11 | target_link_libraries(xwrouter PRIVATE gcov) 12 | endif() 13 | endif() 14 | -------------------------------------------------------------------------------- /tests/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | aux_source_directory(./ xwrouter_test_dir) 2 | 3 | add_executable(xwrouter_test ${xwrouter_test_dir}) 4 | 5 | add_dependencies(xwrouter_test xwrouter xxbase) 6 | 7 | target_link_libraries(xwrouter_test 8 | xwrouter 9 | xkad 10 | xtransport 11 | xpbase 12 | xledger 13 | xcrypto 14 | xutility 15 | xxbase 16 | common 17 | protobuf 18 | -lgtest 19 | -lgmock 20 | -lpthread -ldl 21 | -lrt 22 | ) 23 | 24 | -------------------------------------------------------------------------------- /xwrouter.xcodeproj/xcuserdata/imac.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | xwrouter.xcscheme_^#shared#^_ 8 | 9 | orderHint 10 | 7 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /demo/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | aux_source_directory(./ xwrouter_demo_dir) 2 | add_executable(xwrouter_demo ${xwrouter_demo_dir}) 3 | 4 | add_definitions( 5 | -DUSE_REDIS 6 | ) 7 | 8 | add_dependencies(xwrouter_demo xgossip xkad xxbase xpbase) 9 | 10 | target_link_libraries(xwrouter_demo 11 | xwrouter 12 | xgossip 13 | xkad 14 | xstobject 15 | xtransport 16 | xpbase 17 | xcrypto 18 | xutility 19 | xxbase 20 | xledger 21 | protobuf 22 | -lgtest 23 | -lgmock 24 | -lpthread -ldl 25 | -lrt 26 | ) 27 | 28 | -------------------------------------------------------------------------------- /root/root_message_handler.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2017-2019 Telos Foundation & contributors 2 | // Distributed under the MIT software license, see the accompanying 3 | // file COPYING or http://www.opensource.org/licenses/mit-license.php. 4 | 5 | #pragma once 6 | 7 | #include "xbase/xpacket.h" 8 | #include "xkad/routing_table/routing_utils.h" 9 | #include "xkad/proto/kadmlia.pb.h" 10 | #include "xkad/routing_table/callback_manager.h" 11 | 12 | namespace top { 13 | 14 | namespace wrouter { 15 | 16 | class RootMessageHandler { 17 | public: 18 | RootMessageHandler(); 19 | ~RootMessageHandler(); 20 | void HandleMessage(transport::protobuf::RoutingMessage& message, base::xpacket_t& packet); 21 | 22 | private: 23 | 24 | DISALLOW_COPY_AND_ASSIGN(RootMessageHandler); 25 | }; 26 | 27 | } // namespace wrouter 28 | 29 | } // namespace top 30 | -------------------------------------------------------------------------------- /register_message_handler.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2017-2019 Telos Foundation & contributors 2 | // Distributed under the MIT software license, see the accompanying 3 | // file COPYING or http://www.opensource.org/licenses/mit-license.php. 4 | 5 | #pragma once 6 | 7 | #include 8 | 9 | #include "xkad/proto/kadmlia.pb.h" 10 | #include "xbase/xpacket.h" 11 | #include "xtransport/transport_message_register.h" 12 | 13 | namespace top { 14 | 15 | namespace wrouter { 16 | 17 | void WrouterRegisterMessageHandler(int msg_type, transport::HandlerProc handler_proc); 18 | void WrouterUnregisterMessageHandler(int msg_type); 19 | void WrouterRegisterMessageRequestType(int msg_type, int request_type); 20 | void WrouterUnregisterMessageRequestType(int msg_type); 21 | int WrouterGetRequestType(int msg_type); 22 | void WrouterSelfHandleMessage( 23 | transport::protobuf::RoutingMessage& message, 24 | base::xpacket_t& packet); 25 | 26 | } // namespace wrouter 27 | 28 | } // namespace top 29 | -------------------------------------------------------------------------------- /tests/test_main.cc: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2017-2019 Telos Foundation & contributors 2 | // Distributed under the MIT software license, see the accompanying 3 | // file COPYING or http://www.opensource.org/licenses/mit-license.php. 4 | 5 | #include 6 | #include 7 | 8 | #include "xpbase/base/top_log.h" 9 | #include "xpbase/base/top_config.h" 10 | #include "xkad/routing_table/routing_utils.h" 11 | 12 | namespace top { 13 | 14 | std::shared_ptr global_xid; 15 | uint32_t gloabl_platform_type = kPlatform; 16 | } 17 | 18 | int main(int argc, char *argv[]) { 19 | xinit_log("bitvpn_ut.log", true, true); 20 | xset_log_level(enum_xlog_level_debug); 21 | top::base::Config config; 22 | config.Init("./conf.ut/test_routing_table.conf"); 23 | top::kadmlia::CreateGlobalXid(config); 24 | 25 | testing::GTEST_FLAG(output) = "xml:"; 26 | testing::InitGoogleTest(&argc, argv); 27 | ::testing::InitGoogleMock(&argc, argv); 28 | int ret = RUN_ALL_TESTS(); 29 | TOP_INFO("exit"); 30 | return ret; 31 | } 32 | 33 | -------------------------------------------------------------------------------- /wrouter_utils/wrouter_base_routing.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2017-2019 Telos Foundation & contributors 2 | // Distributed under the MIT software license, see the accompanying 3 | // file COPYING or http://www.opensource.org/licenses/mit-license.php. 4 | 5 | #pragma once 6 | 7 | 8 | #pragma once 9 | 10 | #include 11 | #include 12 | #include 13 | #include 14 | 15 | #include "xpbase/base/top_utils.h" 16 | #include "xpbase/base/top_config.h" 17 | #include "xkad/routing_table/routing_table.h" 18 | #include "xwrouter/wrouter_utils/wrouter_utils.h" 19 | 20 | namespace top { 21 | 22 | namespace wrouter { 23 | 24 | class WrouterBaseRouting : public kadmlia::RoutingTable { 25 | public: 26 | WrouterBaseRouting( 27 | std::shared_ptr transport, 28 | uint32_t kad_key_size, 29 | kadmlia::LocalNodeInfoPtr local_node_ptr) 30 | : kadmlia::RoutingTable(transport, kad_key_size, local_node_ptr) {} 31 | virtual ~WrouterBaseRouting() {} 32 | 33 | protected: 34 | DISALLOW_COPY_AND_ASSIGN(WrouterBaseRouting); 35 | }; 36 | 37 | } // namespace wrouter 38 | 39 | } // namespace top 40 | -------------------------------------------------------------------------------- /wrouter_utils/wrouter_utils.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2017-2019 Telos Foundation & contributors 2 | // Distributed under the MIT software license, see the accompanying 3 | // file COPYING or http://www.opensource.org/licenses/mit-license.php. 4 | 5 | #pragma once 6 | 7 | #include "xkad/routing_table/routing_utils.h" 8 | 9 | namespace top { 10 | 11 | namespace wrouter { 12 | 13 | enum RoutingMessageRequestType { 14 | kNone = 0, 15 | kRequestMsg, 16 | kResponseMsg, 17 | }; 18 | 19 | enum ClientRelayMessageCode { 20 | kErrorReturn = 1, 21 | kContinueReturn, 22 | kFirstRelayRetrun, 23 | }; 24 | 25 | enum enum_platform_xpacket_flag { 26 | kPlatformXpacketInvalid = 100, 27 | kPlatformXpacketRoot, 28 | kPlatformXpacketKadControl, 29 | kPlatformXpacketNatDetect, 30 | }; 31 | 32 | enum enum_platform_xpacket_p2p_factor { 33 | kP2pRandomNumGeneral = 4, 34 | }; 35 | 36 | // get closest node from routing table factor 37 | enum enum_platform_xpacket_broadcast_factor { 38 | kBroadcastGeneral = 1, 39 | kBroadcastMax = kadmlia::kRoutingMaxNodesSize, 40 | }; 41 | 42 | enum enum_platform_xpacket_judge_own { 43 | kJudgeOwnError = 0, 44 | kJudgeOwnYes, 45 | kJudgeOwnYesAndContinue, 46 | kJudgeOwnNoAndContinue, 47 | kJudgeOwnNo, 48 | }; 49 | 50 | enum enum_platform_xpacket_recv { 51 | kRecvError = 0, 52 | kRecvOwn, 53 | kRecvOk, 54 | }; 55 | 56 | } // namespace wrouter 57 | 58 | } // namespace top 59 | -------------------------------------------------------------------------------- /src/register_message_handler.cc: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2017-2019 Telos Foundation & contributors 2 | // Distributed under the MIT software license, see the accompanying 3 | // file COPYING or http://www.opensource.org/licenses/mit-license.php. 4 | 5 | #include "xwrouter/register_message_handler.h" 6 | 7 | #include "xwrouter/message_handler/wrouter_message_handler.h" 8 | #include "xwrouter/message_handler/rumor_message_handler.h" 9 | 10 | namespace top { 11 | 12 | namespace wrouter { 13 | 14 | void WrouterRegisterMessageHandler(int msg_type, transport::HandlerProc handler_proc) { 15 | WrouterMessageHandler::Instance()->AddHandler(msg_type, handler_proc); 16 | } 17 | 18 | void WrouterUnregisterMessageHandler(int msg_type) { 19 | WrouterMessageHandler::Instance()->RemoveHandler(msg_type); 20 | } 21 | 22 | void WrouterRegisterMessageRequestType(int msg_type, int request_type) { 23 | WrouterMessageHandler::Instance()->AddRequestType(msg_type, request_type); 24 | } 25 | 26 | void WrouterUnregisterMessageRequestType(int msg_type) { 27 | WrouterMessageHandler::Instance()->RemoveRequestType(msg_type); 28 | } 29 | 30 | int WrouterGetRequestType(int msg_type) { 31 | return WrouterMessageHandler::Instance()->GetRequestType(msg_type); 32 | } 33 | 34 | void WrouterSelfHandleMessage(transport::protobuf::RoutingMessage& message, base::xpacket_t& packet) { 35 | return WrouterMessageHandler::Instance()->HandleMessage(message, packet); 36 | } 37 | 38 | } // namespace wrouter 39 | 40 | } // namespace top 41 | -------------------------------------------------------------------------------- /multi_routing/small_net_cache.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2017-2019 Telos Foundation & contributors 2 | // Distributed under the MIT software license, see the accompanying 3 | // file COPYING or http://www.opensource.org/licenses/mit-license.php. 4 | 5 | #pragma once 6 | 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | #include "xpbase/base/xip_parser.h" 13 | #include "xpbase/base/top_timer.h" 14 | 15 | 16 | namespace top { 17 | 18 | namespace wrouter { 19 | 20 | typedef struct NetNode { 21 | std::string m_account; 22 | std::string m_public_key; 23 | base::XipParser m_xip; 24 | std::chrono::steady_clock::time_point time_point; 25 | } NetNode; 26 | 27 | class SmallNetNodes { 28 | public: 29 | static SmallNetNodes* Instance(); 30 | bool Init(); 31 | 32 | uint32_t AddNode(NetNode node); 33 | bool FindNode(const std::string& account, NetNode& Fnode); 34 | bool FindNode(uint32_t index, NetNode& Fnode, uint64_t service_type); 35 | bool FindRandomNode(NetNode& Fnode, uint64_t service_type); 36 | bool FindAllNode(std::vector& node_vec, uint64_t service_type); 37 | void do_clear_and_reset(); 38 | 39 | private: 40 | SmallNetNodes(); 41 | ~SmallNetNodes(); 42 | 43 | private: 44 | std::mutex net_nodes_cache_map_mutex_; 45 | // key is service_type 46 | std::unordered_map> net_nodes_cache_map_; 47 | std::shared_ptr clear_timer_{nullptr}; 48 | }; 49 | 50 | } 51 | 52 | } 53 | -------------------------------------------------------------------------------- /src/root_message_handler.cc: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2017-2019 Telos Foundation & contributors 2 | // Distributed under the MIT software license, see the accompanying 3 | // file COPYING or http://www.opensource.org/licenses/mit-license.php. 4 | 5 | #include "xwrouter/root/root_message_handler.h" 6 | 7 | #include "xpbase/base/top_log.h" 8 | #include "xkad/routing_table/routing_table.h" 9 | #include "xwrouter/register_routing_table.h" 10 | #include "xwrouter/register_message_handler.h" 11 | #include "xwrouter/wrouter_utils/wrouter_utils.h" 12 | 13 | namespace top { 14 | 15 | namespace wrouter { 16 | 17 | RootMessageHandler::RootMessageHandler() { 18 | WrouterRegisterMessageHandler(kRootMessage, [this]( 19 | transport::protobuf::RoutingMessage& message, 20 | base::xpacket_t& packet) { 21 | HandleMessage(message, packet); 22 | }); 23 | } 24 | 25 | RootMessageHandler::~RootMessageHandler() { 26 | WrouterUnregisterMessageHandler(kRootMessage); 27 | } 28 | 29 | void RootMessageHandler::HandleMessage( 30 | transport::protobuf::RoutingMessage& message, 31 | base::xpacket_t& packet) { 32 | auto routing_table = GetRoutingTable( 33 | message.des_service_type(), 34 | message.has_is_root() && message.is_root()); 35 | if (!routing_table) { 36 | TOP_ERROR("service type[%llu] has not register routing table.", 37 | message.des_service_type()); 38 | return; 39 | } 40 | routing_table->HandleMessage(message, packet); 41 | } 42 | 43 | } // namespace wrouter 44 | 45 | } // namespace top 46 | -------------------------------------------------------------------------------- /message_handler/rumor_message_handler.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2017-2019 Telos Foundation & contributors 2 | // Distributed under the MIT software license, see the accompanying 3 | // file COPYING or http://www.opensource.org/licenses/mit-license.php. 4 | 5 | #pragma once 6 | #include 7 | #include 8 | 9 | #include "xwrouter/register_message_handler.h" 10 | #include "xkad/routing_table/routing_utils.h" 11 | #include "xtransport/transport_message_register.h" 12 | #include "xpbase/base/manager_template.h" 13 | #include "xkad/gossip/rumor_def.h" 14 | #include "xkad/gossip/rumor_filter.h" 15 | 16 | namespace top { 17 | namespace gossip { 18 | 19 | class RumorMessageHandler : public ManagerTemplate { 20 | public: 21 | static RumorMessageHandler* Instance(); 22 | void AddHandle(uint32_t message_type, transport::HandlerProc proc); 23 | void RemoveHandle(int32_t message_type); 24 | void SetMaxHopNum(const int32_t); 25 | private: 26 | RumorMessageHandler() : 27 | max_hop_num_(kDefautHopCount) {} 28 | ~RumorMessageHandler() {} 29 | bool CheckMessage( 30 | int32_t, 31 | const transport::protobuf::RoutingMessage&) const; 32 | bool IsHopExpired( 33 | const int32_t) const; 34 | void HandleMessage( 35 | transport::protobuf::RoutingMessage&, 36 | base::xpacket_t&); 37 | std::atomic max_hop_num_; 38 | transport::MessageManagerIntf* message_manager_{transport::MessageManagerIntf::Instance()}; 39 | }; 40 | typedef std::shared_ptr RumorMessageHandlerSptr; 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /demo/main.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2017-2019 Telos Foundation & contributors 2 | // Distributed under the MIT software license, see the accompanying 3 | // file COPYING or http://www.opensource.org/licenses/mit-license.php. 4 | 5 | #pragma once 6 | 7 | #include 8 | #include 9 | #include // NOLINT 10 | 11 | #include "xpbase/base/line_parser.h" 12 | #include "xpbase/base/top_utils.h" 13 | #include "xpbase/base/top_timer.h" 14 | #include "xpbase/base/top_log.h" 15 | #include "xpbase/base/args_parser.h" 16 | #include "xpbase/base/top_config.h" 17 | #include "xpbase/base/check_cast.h" 18 | #include "xpbase/base/endpoint_util.h" 19 | #include "xpbase/base/kad_key/platform_kadmlia_key.h" 20 | #include "xpbase/base/redis_client.h" 21 | #include "xtransport/udp_transport/udp_transport.h" 22 | #include "xkad/routing_table/routing_table.h" 23 | #include "xkad/routing_table/routing_utils.h" 24 | #include "commands.h" 25 | #include "xkad/routing_table/local_node_info.h" 26 | #include "xwrouter/register_routing_table.h" 27 | #include "xwrouter/root/root_routing_manager.h" 28 | #include "xwrouter/multi_routing/small_net_cache.h" 29 | #include "xwrouter/root/root_routing.h" 30 | #include "xtransport/message_manager/multi_message_handler.h" 31 | #include "xkad/nat_detect/nat_manager_intf.h" 32 | #include "xwrouter/xwrouter.h" 33 | #include "cpp_redis/core/client.hpp" 34 | #include "xgossip/include/block_sync_manager.h" 35 | #include "xtransport/udp_config.h" 36 | #include "xstobject/xledger_db.h" 37 | #include "xwrouter/multi_routing/small_net_cache.h" 38 | #include "demo_routing.h" 39 | 40 | namespace top { 41 | 42 | static const std::string kKadmliaKeyDbKey = "KADMLIA_KEY_DB_KEY"; 43 | 44 | /* 45 | int KadKey_GetFromDb( 46 | base::KadmliaKeyPtr& kadkey, 47 | std::shared_ptr db_face, 48 | const std::string& db_field); 49 | 50 | int KadKey_StoreInDb( 51 | base::KadmliaKeyPtr& kadkey, 52 | std::shared_ptr db_face, 53 | const std::string& db_field); 54 | */ 55 | 56 | } // namespace top 57 | -------------------------------------------------------------------------------- /register_routing_table.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2017-2019 Telos Foundation & contributors 2 | // Distributed under the MIT software license, see the accompanying 3 | // file COPYING or http://www.opensource.org/licenses/mit-license.php. 4 | 5 | #pragma once 6 | 7 | #include 8 | #include 9 | #include 10 | 11 | #include "xkad/proto/kadmlia.pb.h" 12 | #include "xkad/routing_table/routing_utils.h" 13 | #include "xbase/xpacket.h" 14 | #include "xpbase/base/kad_key/get_kadmlia_key.h" 15 | #include "xwrouter/root/root_routing.h" 16 | 17 | namespace top { 18 | 19 | namespace kadmlia { 20 | class RoutingTable; 21 | class LocalNodeInfo; 22 | class CallbackManager; 23 | struct NodeInfo; 24 | 25 | typedef std::shared_ptr NodeInfoPtr; 26 | } 27 | 28 | namespace transport { 29 | class UdpTransport; 30 | } 31 | 32 | namespace wrouter { 33 | 34 | class RootRoutingManager; 35 | 36 | void RegisterRoutingTable(uint64_t type, std::shared_ptr routing_table); 37 | void UnregisterRoutingTable(uint64_t type); 38 | void UnregisterAllRoutingTable(); 39 | std::shared_ptr GetRoutingTable(const uint64_t& type, bool root = false); 40 | std::shared_ptr GetRoutingTable(const std::string& routing_id, bool root = false); 41 | void SetRootRoutingManager(std::shared_ptr root_manager_ptr); 42 | void GetAllRegisterType(std::vector& vec_type); 43 | bool CheckTypeExist(uint64_t type); 44 | std::shared_ptr GetSmartRoutingTable(uint64_t type); 45 | uint64_t TryGetSmartRoutingTable(uint64_t type); 46 | bool SetCacheServiceType(uint64_t service_type); 47 | bool GetServiceBootstrapRootNetwork( 48 | uint64_t service_type, 49 | std::set>& boot_endpoints); 50 | 51 | int NetworkExists( 52 | base::KadmliaKeyPtr& kad_key_ptr, 53 | std::set>& endpoints); 54 | int GetSameNetworkPublicEndpoints( 55 | base::KadmliaKeyPtr& kad_key_ptr, 56 | std::set>& boot_endpoints); 57 | int GetSameNetworkNodes( 58 | base::KadmliaKeyPtr& kad_key_ptr, 59 | std::vector& ret_nodes); 60 | 61 | } // namespace wrouter 62 | 63 | } // namespace top 64 | -------------------------------------------------------------------------------- /root/root_routing_manager.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2017-2019 Telos Foundation & contributors 2 | // Distributed under the MIT software license, see the accompanying 3 | // file COPYING or http://www.opensource.org/licenses/mit-license.php. 4 | 5 | #pragma once 6 | 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | #include "xpbase/base/top_utils.h" 13 | #include "xpbase/base/top_config.h" 14 | #include "xpbase/base/kad_key/kadmlia_key.h" 15 | #include "xkad/routing_table/node_info.h" 16 | 17 | namespace top { 18 | 19 | namespace kadmlia { 20 | class RoutingTable; 21 | } 22 | 23 | namespace transport { 24 | class Transport; 25 | } 26 | 27 | namespace wrouter { 28 | 29 | class RootRoutingManager { 30 | public: 31 | RootRoutingManager(); 32 | ~RootRoutingManager(); 33 | int AddRoutingTable( 34 | std::shared_ptr transport, 35 | const base::Config& config, 36 | base::KadmliaKeyPtr kad_key_ptr, 37 | bool wait_for_joined = true); 38 | void RemoveRoutingTable(uint64_t service_type); 39 | void RemoveAllRoutingTable(); 40 | std::shared_ptr GetRoutingTable(uint64_t service_type); 41 | std::shared_ptr GetRoutingTable(const std::string& routing_id); 42 | int GetRootNodes(uint32_t network_id, std::vector& root_nodes); 43 | int GetRootNodes( 44 | const std::string& des_id, 45 | std::vector& root_nodes); 46 | int GetRootBootstrapCache( 47 | std::set>& boot_endpoints); 48 | int GetBootstrapRootNetwork( 49 | uint64_t service_type, 50 | std::set>& boot_endpoints); 51 | 52 | bool GetServiceBootstrapRootNetwork( 53 | uint64_t service_type, 54 | std::set>& boot_endpoints); 55 | bool SetCacheServiceType(uint64_t service_type); 56 | 57 | private: 58 | int CreateRoutingTable( 59 | std::shared_ptr transport, 60 | const base::Config& config, 61 | base::KadmliaKeyPtr kad_key_ptr, 62 | bool wait_for_joined); 63 | 64 | private: 65 | std::map> root_routing_map_; 66 | std::mutex root_routing_map_mutex_; 67 | 68 | DISALLOW_COPY_AND_ASSIGN(RootRoutingManager); 69 | }; 70 | 71 | } // namespace wrouter 72 | 73 | } // namespace top 74 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # xwrouter 2 | 3 | A High Performance intelligent routing module. 4 | 5 | ## Feature highlights 6 | 7 | + Fully designed for Multi-Cores and Muti-Threads 8 | + High Performance & Low memory/cpu consumption 9 | + intelligent routing for point-to-point communication and broadcast communication 10 | + multilayered network implementation 11 | + Cross-Network Communication Techniques 12 | + iOS, Android, Windows, MacOS, Linux support 13 | 14 | 15 | ## Example 16 | 17 | ### C++ example 18 | 19 | the demo program can be found in demo or tests directory. 20 | 21 | ``` 22 | int main(int argc, char** argv) { 23 | #ifdef _WIN32 24 | // register signal 25 | if (signal(SIGTERM, top::SignalCatch) == SIG_ERR || 26 | signal(SIGINT, top::SignalCatch) == SIG_ERR) { 27 | TOP_FATAL("signal failed"); 28 | return 1; 29 | } 30 | #else 31 | // register signal 32 | if (signal(SIGPIPE, SIG_IGN) == SIG_ERR || 33 | signal(SIGTERM, top::SignalCatch) == SIG_ERR || 34 | signal(SIGINT, top::SignalCatch) == SIG_ERR) { 35 | TOP_FATAL("signal failed"); 36 | return 1; 37 | } 38 | #endif 39 | top::base::Config config; 40 | if (top::HandleParamsAndConfig(argc, argv, config) != 0) { 41 | TOP_FATAL("handle params and config failed!"); 42 | return 1; 43 | } 44 | 45 | if (top::InitDb(config) != 0) { 46 | TOP_FATAL("init db failed!"); 47 | return 1; 48 | } 49 | 50 | if (!top::kadmlia::CreateGlobalXid(config)) { 51 | TOP_FATAL("create global xid failed"); 52 | return 1; 53 | } 54 | top::kadmlia::CallbackManager::Instance(); 55 | top::wrouter::SmallNetNodes::Instance(); 56 | top::wrouter::SmallNetNodes::Instance()->Init(); 57 | 58 | #ifdef USE_REDIS 59 | std::string redis_ip; 60 | config.Get("redis", "ip", redis_ip); 61 | uint16_t redis_port; 62 | config.Get("redis", "port", redis_port); 63 | std::cout << "now connect redis: " << redis_ip << ":" << redis_port << std::endl; 64 | try { 65 | if (!top::base::RedisClient::Instance()->Start(redis_ip, redis_port)) { 66 | std::cout << "start redis failed!" << std::endl; 67 | return 1; 68 | } 69 | } catch (...) {} 70 | #endif 71 | 72 | int res = top::MainEdge(config); 73 | TOP_FATAL("main exit: %d", res); 74 | return res; 75 | } 76 | ``` 77 | 78 | 79 | ## Contact 80 | 81 | [TOP Network](https://www.topnetwork.org/) 82 | 83 | ## License 84 | 85 | Copyright (c) 2017-2019 Telos Foundation & contributors 86 | 87 | Distributed under the MIT software license, see the accompanying 88 | 89 | file COPYING or http://www.opensource.org/licenses/mit-license.php. -------------------------------------------------------------------------------- /xwrouter.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2017-2019 Telos Foundation & contributors 2 | // Distributed under the MIT software license, see the accompanying 3 | // file COPYING or http://www.opensource.org/licenses/mit-license.php. 4 | 5 | #pragma once 6 | 7 | #include 8 | 9 | #include "xkad/routing_table/callback_manager.h" 10 | #include "xwrouter/wrouter_utils/wrouter_utils.h" 11 | #include "xbase/xbase.h" 12 | #include "xbase/xrouter.h" 13 | #include "xgossip/include/broadcast_layered.h" 14 | #include "xgossip/gossip_interface.h" 15 | #include "xwrouter/message_handler/xwrouter_handler.h" 16 | 17 | namespace top { 18 | 19 | namespace transport { 20 | class MultiThreadHandler; 21 | class Transport; 22 | typedef std::shared_ptr TransportPtr; 23 | 24 | namespace protobuf { 25 | class RoutingMessage; 26 | }; 27 | }; 28 | 29 | namespace kadmlia { 30 | class RoutingTable; 31 | struct NodeInfo; 32 | typedef std::shared_ptr RoutingTablePtr; 33 | typedef std::shared_ptr NodeInfoPtr; 34 | }; 35 | 36 | namespace wrouter { 37 | 38 | using Xip2Header = _xip2_header; 39 | 40 | using on_receive_own_callback_t = 41 | std::function; 42 | 43 | class Wrouter { 44 | public: 45 | static Wrouter* Instance(); 46 | void Init( 47 | base::xcontext_t& context, 48 | const uint32_t thread_id, 49 | transport::TransportPtr transport_ptr, 50 | const uint32_t max_broadcast_num); 51 | int32_t send(base::xpacket_t& packet); 52 | int32_t send(transport::protobuf::RoutingMessage& message); 53 | int32_t SendToLocal(transport::protobuf::RoutingMessage& message); 54 | int32_t SendDirect( 55 | transport::protobuf::RoutingMessage& message, 56 | const std::string& ip, 57 | uint16_t port); 58 | virtual int32_t recv( 59 | transport::protobuf::RoutingMessage& message, 60 | base::xpacket_t& packet); 61 | std::vector GetAllLocalIds(); 62 | std::vector GetAllLocalXips(); 63 | void SupportRandomPattern(); 64 | void register_on_receive_own_callback(on_receive_own_callback_t callback); 65 | void unregister_on_receive_own_callback(); 66 | Xip2Header* ParserXip2Header(base::xpacket_t& packet); 67 | bool BroadcastByMultiRandomKadKey( 68 | const transport::protobuf::RoutingMessage& message, 69 | kadmlia::ResponseFunctor call_back, 70 | int64_t recursive_count = kRecursiveCount); 71 | 72 | int32_t HandleOwnSyncPacket(transport::protobuf::RoutingMessage& message, base::xpacket_t& packet); 73 | private: 74 | Wrouter(); 75 | ~Wrouter(); 76 | 77 | int32_t HandleOwnPacket(transport::protobuf::RoutingMessage& message, base::xpacket_t& packet); 78 | int32_t HandleOwnPacket(base::xpacket_t& packet); 79 | private: 80 | std::mutex callback_mutex_; 81 | on_receive_own_callback_t callback_; 82 | uint32_t max_broadcast_num_; 83 | 84 | std::shared_ptr wxid_handler_; 85 | std::shared_ptr wxip_handler_; 86 | DISALLOW_COPY_AND_ASSIGN(Wrouter); 87 | }; 88 | 89 | } // namespace wrouter 90 | 91 | } // namespace top 92 | -------------------------------------------------------------------------------- /root/root_routing.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2017-2019 Telos Foundation & contributors 2 | // Distributed under the MIT software license, see the accompanying 3 | // file COPYING or http://www.opensource.org/licenses/mit-license.php. 4 | 5 | #pragma once 6 | 7 | #include "xpbase/base/top_config.h" 8 | #include "xpbase/base/top_utils.h" 9 | #include "xkad/routing_table/routing_table.h" 10 | #include "xtransport/transport.h" 11 | #include "xwrouter/root/root_message_handler.h" 12 | #include "xwrouter/wrouter_utils/wrouter_utils.h" 13 | #include "xwrouter/wrouter_utils/wrouter_base_routing.h" 14 | 15 | namespace top { 16 | 17 | namespace kadmlia { 18 | class RoutingTable; 19 | typedef std::shared_ptr RoutingTablePtr; 20 | }; 21 | 22 | namespace wrouter { 23 | 24 | enum RootMessageType { 25 | kGetNodesRequest = 1, 26 | kGetNodesResponse = 2, 27 | }; 28 | 29 | 30 | class RootRouting : public wrouter::WrouterBaseRouting { 31 | public: 32 | RootRouting(std::shared_ptr, kadmlia::LocalNodeInfoPtr); 33 | virtual ~RootRouting() override; 34 | virtual bool Init() override; 35 | virtual bool UnInit() override; 36 | virtual void HandleMessage( 37 | transport::protobuf::RoutingMessage& message, 38 | base::xpacket_t& packet) override; 39 | virtual int AddNode(kadmlia::NodeInfoPtr node) override; 40 | virtual int DropNode(kadmlia::NodeInfoPtr node) override; 41 | virtual void SetFreqMessage(transport::protobuf::RoutingMessage& message) override; 42 | int GetRootNodes(uint64_t sevice_type, std::vector& root_nodes); 43 | int GetRootNodes(const std::string& des_id, std::vector& root_nodes); 44 | void AddNetworkRootId(const std::string& root_id); 45 | void RemoveNetworkRootId(const std::string& root_id); 46 | bool ContainRootId(const std::string& id); 47 | // add target service_type to be cached 48 | bool SetCacheServiceType(uint64_t service_type); 49 | // get cache nodes of service_type give 50 | bool GetCacheServicePublicNodes( 51 | uint64_t service_type, 52 | std::set>& boot_endpoints); 53 | kadmlia::RoutingTablePtr FindRoutingTable(const std::string& msg_des_node_id); 54 | bool GetRootNodesFromLocalRootRouting( 55 | kadmlia::RoutingTablePtr root_routing, 56 | const std::string& node_id, 57 | std::vector& nodes); 58 | bool GetRootNodesFromLocal(const std::string& node_id, std::vector& nodes); 59 | 60 | protected: 61 | virtual bool NewNodeReplaceOldNode(kadmlia::NodeInfoPtr node, bool remove); 62 | 63 | private: 64 | virtual int Bootstrap( 65 | const std::string& peer_ip, 66 | uint16_t peer_port, 67 | uint64_t des_service_type) override; 68 | void HandleRootGetNodesRequest(transport::protobuf::RoutingMessage& message, base::xpacket_t& packet); 69 | void HandleRootGetNodesResponse(transport::protobuf::RoutingMessage& message, base::xpacket_t& packet); 70 | virtual bool StartBootstrapCacheSaver() override; 71 | 72 | static RootMessageHandler root_message_handler_; 73 | std::set root_id_set_; 74 | std::mutex root_id_set_mutex_; 75 | 76 | DISALLOW_COPY_AND_ASSIGN(RootRouting); 77 | }; 78 | 79 | } // namespace wrouter 80 | 81 | } // namespace top 82 | -------------------------------------------------------------------------------- /message_handler/xwrouter_xip_handler.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2017-2019 Telos Foundation & contributors 2 | // Distributed under the MIT software license, see the accompanying 3 | // file COPYING or http://www.opensource.org/licenses/mit-license.php. 4 | 5 | #pragma once 6 | 7 | #include 8 | 9 | #include "xwrouter/message_handler/xwrouter_handler.h" 10 | #include "xkad/routing_table/callback_manager.h" 11 | #include "xwrouter/wrouter_utils/wrouter_utils.h" 12 | #include "xbase/xbase.h" 13 | #include "xbase/xrouter.h" 14 | #include "xgossip/include/broadcast_layered.h" 15 | #include "xgossip/gossip_interface.h" 16 | 17 | namespace top { 18 | 19 | namespace transport { 20 | class MultiThreadHandler; 21 | class Transport; 22 | typedef std::shared_ptr TransportPtr; 23 | 24 | namespace protobuf { 25 | class RoutingMessage; 26 | }; 27 | }; 28 | 29 | namespace base { 30 | class XipParser; 31 | }; 32 | 33 | namespace kadmlia { 34 | class RoutingTable; 35 | struct NodeInfo; 36 | typedef std::shared_ptr RoutingTablePtr; 37 | typedef std::shared_ptr NodeInfoPtr; 38 | }; 39 | 40 | namespace gossip { 41 | class GossipInterface; 42 | } 43 | 44 | namespace wrouter { 45 | 46 | using Xip2Header = _xip2_header; 47 | 48 | class WrouterXipHandler : public WrouterHandler { 49 | public: 50 | WrouterXipHandler( 51 | transport::TransportPtr transport_ptr, 52 | std::shared_ptr bloom_gossip_ptr, 53 | std::shared_ptr layered_gossip_ptr, 54 | std::shared_ptr bloom_layer_gossip_ptr, 55 | std::shared_ptr set_layer_gossip_ptr); 56 | 57 | ~WrouterXipHandler(); 58 | 59 | public: 60 | virtual int32_t SendPacket(base::xpacket_t& packet) override; 61 | virtual int32_t RecvPacket(base::xpacket_t& packet) override; 62 | virtual int32_t SendToLocal(base::xpacket_t& packet) override; 63 | virtual int32_t SendDirect( 64 | base::xpacket_t& packet, 65 | const std::string& ip, 66 | uint16_t port) override; 67 | 68 | private: 69 | Xip2Header* ParserXip2Header(base::xpacket_t& packet); 70 | bool ParserDesXip(Xip2Header* xip2_header, base::XipParser& des_xip); 71 | uint64_t ParserServiceType(uint64_t to_xip_addr_low, uint64_t to_xip_addr_high); 72 | 73 | bool MulticastPacketCheck(Xip2Header* xip2_header); 74 | bool GossipPacketCheck(Xip2Header* xip2_header); 75 | 76 | int32_t SendMulticast(Xip2Header* xip2_header, base::xpacket_t& packet); 77 | int32_t SendGossip(Xip2Header* xip2_header, base::xpacket_t& packet); 78 | int32_t SendGeneral(Xip2Header* xip2_header, base::xpacket_t& packet); 79 | 80 | // judge packet arrive the dest or not 81 | int32_t JudgeOwnPacket(base::xpacket_t& packet); 82 | int32_t JudgeOwnPacketMulticast(Xip2Header* xip2_header, base::xpacket_t& packet); 83 | 84 | int32_t GossipBroadcast( 85 | const std::string& routing_local_id, 86 | base::xpacket_t& packet, 87 | const std::vector& neighbors, 88 | bool use_filter); 89 | int32_t SendData( 90 | base::xpacket_t& packet, 91 | const std::vector& neighbors, 92 | uint32_t next_size, 93 | bool broadcast_stride); 94 | 95 | private: 96 | DISALLOW_COPY_AND_ASSIGN(WrouterXipHandler); 97 | }; 98 | 99 | } // namespace wrouter 100 | 101 | } // namespace top 102 | -------------------------------------------------------------------------------- /message_handler/xwrouter_handler.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2017-2019 Telos Foundation & contributors 2 | // Distributed under the MIT software license, see the accompanying 3 | // file COPYING or http://www.opensource.org/licenses/mit-license.php. 4 | 5 | #pragma once 6 | 7 | #include 8 | 9 | #include "xbase/xbase.h" 10 | #include "xbase/xrouter.h" 11 | 12 | namespace top { 13 | 14 | namespace transport { 15 | class MultiThreadHandler; 16 | class Transport; 17 | typedef std::shared_ptr TransportPtr; 18 | 19 | namespace protobuf { 20 | class RoutingMessage; 21 | }; 22 | }; 23 | 24 | namespace base { 25 | class XipParser; 26 | }; 27 | 28 | namespace kadmlia { 29 | class RoutingTable; 30 | struct NodeInfo; 31 | typedef std::shared_ptr RoutingTablePtr; 32 | typedef std::shared_ptr NodeInfoPtr; 33 | }; 34 | 35 | namespace gossip { 36 | class GossipInterface; 37 | } 38 | 39 | namespace wrouter { 40 | 41 | using Xip2Header = _xip2_header; 42 | 43 | class WrouterHandler { 44 | public: 45 | WrouterHandler( 46 | transport::TransportPtr transport_ptr, 47 | std::shared_ptr bloom_gossip_ptr, 48 | std::shared_ptr layered_gossip_ptr, 49 | std::shared_ptr bloom_layer_gossip_ptr, 50 | std::shared_ptr set_layer_gossip_ptr); 51 | virtual ~WrouterHandler(); 52 | 53 | // xip 54 | virtual int32_t SendPacket(base::xpacket_t& packet) { return 0; } 55 | virtual int32_t RecvPacket(base::xpacket_t& packet) { return 0; } 56 | virtual int32_t SendToLocal(base::xpacket_t& packet) { return 0; } 57 | virtual int32_t SendDirect( 58 | base::xpacket_t& packet, 59 | const std::string& ip, 60 | uint16_t port) { return 0; } 61 | 62 | // xid 63 | virtual int32_t SendPacket(transport::protobuf::RoutingMessage& message) { return 0; } 64 | virtual int32_t RecvPacket( 65 | transport::protobuf::RoutingMessage& message, 66 | base::xpacket_t& packet) { return 0; } 67 | virtual int32_t SendToLocal(transport::protobuf::RoutingMessage& message) { return 0; } 68 | virtual int32_t SendDirect( 69 | transport::protobuf::RoutingMessage& message, 70 | const std::string& ip, 71 | uint16_t port) { return 0; } 72 | 73 | virtual bool CloserToTarget( 74 | const std::string& id1, 75 | const std::string& id2, 76 | const std::string& target_id); 77 | 78 | protected: 79 | kadmlia::RoutingTablePtr FindRoutingTable( 80 | bool is_root, 81 | uint64_t service_type, 82 | bool root_backup, 83 | const std::string msg_des_node_id = ""); 84 | std::vector GetClosestNodes( 85 | kadmlia::RoutingTablePtr routing_table, 86 | const std::string& target_id, 87 | uint32_t number_to_get, 88 | bool base_xip); 89 | std::vector GetRandomNodes(std::vector& neighbors,uint32_t number_to_get) const; 90 | 91 | protected: 92 | transport::TransportPtr transport_ptr_; 93 | std::shared_ptr bloom_gossip_ptr_; 94 | std::shared_ptr layered_gossip_ptr_; 95 | std::shared_ptr bloom_layer_gossip_ptr_; 96 | std::shared_ptr set_layer_gossip_ptr_; 97 | }; 98 | 99 | } // namespace wrouter 100 | 101 | } // namespace top 102 | -------------------------------------------------------------------------------- /multi_routing/multi_routing.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2017-2019 Telos Foundation & contributors 2 | // Distributed under the MIT software license, see the accompanying 3 | // file COPYING or http://www.opensource.org/licenses/mit-license.php. 4 | 5 | #pragma once 6 | 7 | #include 8 | #include 9 | #include 10 | 11 | #include "xpbase/base/top_config.h" 12 | #include "xpbase/base/top_timer.h" 13 | #include "xkad/routing_table/routing_utils.h" 14 | #include "xkad/routing_table/routing_table.h" 15 | #include "xwrouter/register_routing_table.h" 16 | #include "xkad/proto/kadmlia.pb.h" 17 | 18 | namespace top { 19 | 20 | namespace wrouter { 21 | 22 | class RootRoutingManager; 23 | 24 | class MultiRouting { 25 | public: 26 | static MultiRouting* Instance(); 27 | kadmlia::RoutingTablePtr GetRoutingTable(const uint64_t& type, bool root = false); 28 | kadmlia::RoutingTablePtr GetRoutingTable(const std::string& routing_id, bool root = false); 29 | private: 30 | friend void RegisterRoutingTable( 31 | uint64_t type, 32 | std::shared_ptr routing_table); 33 | friend void UnregisterRoutingTable(uint64_t type); 34 | friend void UnregisterAllRoutingTable(); 35 | friend std::shared_ptr GetRoutingTable(const uint64_t& type, bool root); 36 | friend std::shared_ptr GetRoutingTable(const std::string& routing_id, bool root); 37 | friend void SetRootRoutingManager(std::shared_ptr root_manager_ptr); 38 | friend void GetAllRegisterType(std::vector& vec_type); 39 | friend bool CheckTypeExist(uint64_t type); 40 | friend std::shared_ptr GetSmartRoutingTable(uint64_t type); 41 | friend uint64_t TryGetSmartRoutingTable(uint64_t type); 42 | friend bool GetServiceBootstrapRootNetwork( 43 | uint64_t service_type, 44 | std::set>& boot_endpoints); 45 | friend bool SetCacheServiceType(uint64_t service_type); 46 | void AddRoutingTable(uint64_t type, kadmlia::RoutingTablePtr routing_table); 47 | void RemoveRoutingTable(uint64_t type); 48 | void RemoveAllRoutingTable(); 49 | void SetRootRoutingManager(std::shared_ptr root_manager_ptr); 50 | void GetAllRegisterType(std::vector& vec_type); 51 | bool CheckTypeExist(uint64_t type); 52 | kadmlia::RoutingTablePtr GetServiceRoutingTable(const uint64_t& type); 53 | kadmlia::RoutingTablePtr GetServiceRoutingTable(const std::string& routing_id); 54 | kadmlia::RoutingTablePtr GetSmartRoutingTable(uint64_t type); 55 | uint64_t TryGetSmartRoutingTable(uint64_t type); 56 | 57 | bool GetServiceBootstrapRootNetwork( 58 | uint64_t service_type, 59 | std::set>& boot_endpoints); 60 | bool SetCacheServiceType(uint64_t service_type); 61 | 62 | // be careful, will change message 63 | void SendToNetwork(transport::protobuf::RoutingMessage& message, bool add_hop = true); 64 | // be careful, will not change message 65 | void SendToNetwork(const transport::protobuf::RoutingMessage& message, bool add_hop = true); 66 | void CheckSingleNodeNetwork(); 67 | 68 | MultiRouting(); 69 | ~MultiRouting(); 70 | 71 | std::map routing_table_map_; 72 | std::mutex routing_table_map_mutex_; 73 | std::shared_ptr root_manager_ptr_; 74 | base::TimerRepeated timer_{base::TimerManager::Instance(), "MultiRouting"}; 75 | 76 | DISALLOW_COPY_AND_ASSIGN(MultiRouting); 77 | }; 78 | 79 | } // namespace wrouter 80 | 81 | } // namespace top 82 | -------------------------------------------------------------------------------- /demo/commands.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2017-2019 Telos Foundation & contributors 2 | // Distributed under the MIT software license, see the accompanying 3 | // file COPYING or http://www.opensource.org/licenses/mit-license.php. 4 | 5 | #pragma once 6 | 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | 16 | #include "xkad/routing_table/node_info.h" 17 | #include "xkad/routing_table/routing_utils.h" 18 | #include "routing_performance/routing_performance.h" 19 | #include "xpbase/base/xip_parser.h" 20 | #include "xpbase/base/top_timer.h" 21 | 22 | namespace top { 23 | 24 | using Arguments = std::vector; 25 | using CommandProc = std::function; 26 | using MapCommands = std::map; 27 | 28 | 29 | namespace kadmlia { 30 | class RoutingTable; 31 | } 32 | 33 | namespace base { 34 | class xpacket_t; 35 | }; 36 | 37 | namespace transport { 38 | namespace protobuf { 39 | class RoutingMessage; 40 | }; 41 | }; 42 | 43 | namespace wrouter { 44 | class Wrouter; 45 | }; 46 | 47 | struct PacketInfo { 48 | uint32_t des_network_id; 49 | uint32_t msg_hash; 50 | uint32_t hop_num; 51 | uint64_t spread_time; 52 | std::string msg_src_id; 53 | }; 54 | 55 | 56 | class TopCommands { 57 | public: 58 | static TopCommands* Instance(); 59 | bool Init(bool first_node, bool show_cmd); 60 | void Run(); 61 | void Destroy() { destroy_ = true; } 62 | 63 | 64 | void ProcessCommand(const std::string& cmdline); 65 | protected: 66 | TopCommands(); 67 | ~TopCommands(); 68 | virtual bool InitExtra() { return true; } 69 | void AddCommand(const std::string& cmd_name, CommandProc cmd_proc); 70 | void AddBaseCommands(); 71 | virtual void AddExtraCommands() {} 72 | void PrintUsage(); 73 | 74 | // 75 | int GetRootNodes(uint64_t service_type); 76 | int GetRootNodes(const std::string& hex_target_id); 77 | void PrintStat(); 78 | 79 | void TestChainTrade( 80 | transport::protobuf::RoutingMessage& message, 81 | uint32_t des_network_id, 82 | uint32_t test_num, 83 | uint32_t backup, 84 | uint32_t neighbors_num, 85 | uint32_t stop_times, 86 | uint32_t max_hop_num, 87 | uint32_t evil_rate, 88 | uint32_t gossip_type, 89 | uint32_t layer_switch_hop_num, 90 | uint32_t left_overlap, 91 | uint32_t right_overlap, 92 | bool block_header = false); 93 | 94 | void HandleTestChainTrade( 95 | transport::protobuf::RoutingMessage& message, 96 | base::xpacket_t& packet); 97 | void PrintRoutingTable(uint64_t service_type, bool root = false); 98 | void GetRootNodes(uint32_t xnetwork_id, std::vector& nodes); 99 | 100 | 101 | std::mutex wait_mutex_; 102 | std::condition_variable wait_cond_var_; 103 | std::mutex init_mutex_; 104 | bool first_node_; 105 | bool show_cmd_; 106 | bool inited_; 107 | bool destroy_; 108 | 109 | std::mutex map_commands_mutex_; 110 | MapCommands map_commands_; 111 | std::shared_ptr test_timer_ {nullptr}; 112 | 113 | std::mutex stat_map_mutex_; 114 | std::map>> stat_map_; 115 | std::shared_ptr stat_map_timer_ {nullptr}; 116 | }; 117 | 118 | } // namespace top 119 | -------------------------------------------------------------------------------- /src/rumor_message_handler.cc: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2017-2019 Telos Foundation & contributors 2 | // Distributed under the MIT software license, see the accompanying 3 | // file COPYING or http://www.opensource.org/licenses/mit-license.php. 4 | 5 | #include "xwrouter/message_handler/rumor_message_handler.h" 6 | 7 | #include "xkad/gossip/rumor_handler.h" 8 | #include "xwrouter/message_handler/wrouter_message_handler.h" 9 | #include "xkad/routing_table/local_node_info.h" 10 | #include "xkad/gossip/rumor_def.h" 11 | #include "xtransport/message_manager/message_manager_intf.h" 12 | 13 | namespace top { 14 | namespace gossip { 15 | 16 | RumorMessageHandler* RumorMessageHandler::Instance() { 17 | static RumorMessageHandler ins; 18 | return &ins; 19 | } 20 | 21 | void RumorMessageHandler::AddHandle(uint32_t message_type, transport::HandlerProc proc) { 22 | if (HaveKey(message_type)) { 23 | TOP_WARN("RumorMessageHandler::AddHandle Failed.Already HaveKey.Message Type:%d", 24 | message_type); 25 | return; 26 | } 27 | wrouter::WrouterRegisterMessageHandler( 28 | message_type, 29 | std::bind( 30 | &RumorMessageHandler::HandleMessage, 31 | this, std::placeholders::_1, 32 | std::placeholders::_2)); 33 | if (!AddData(message_type, proc)) { 34 | TOP_WARN("RumorMessageHandler::AddHandle Failed.AddData Failed.Message Type:%d", 35 | message_type); 36 | return; 37 | } 38 | } 39 | 40 | void RumorMessageHandler::RemoveHandle(int32_t message_type) { 41 | if (!HaveKey(message_type)) { 42 | TOP_WARN("RumorMessageHandler::RemoveHandle Failed.Do not HaveKey.Message Type:%d", 43 | message_type); 44 | return; 45 | } 46 | message_manager_->UnRegisterMessageProcessor(message_type); 47 | DeleteKey(message_type); 48 | } 49 | 50 | void RumorMessageHandler::SetMaxHopNum( 51 | const int32_t hop_num) { 52 | max_hop_num_ = hop_num; 53 | } 54 | 55 | bool RumorMessageHandler::CheckMessage( 56 | int32_t message_type, 57 | const transport::protobuf::RoutingMessage& in_message) const { 58 | transport::protobuf::RoutingMessage message = in_message; 59 | if (message_type != message.type()) { 60 | TOP_WARN("RumorMessageHandler::CheckMessage Failed.Message Type Is Not Equal:%d-%d", 61 | message_type, message.type()); 62 | return false; 63 | } 64 | if (RumorFilter::Instance()->FiltMessage(message)) { 65 | TOP_WARN("RumorFilter::FiltMessageFailed.Message Type Is :%d", 66 | message_type); 67 | return false; 68 | } 69 | int32_t hop_num = message.hop_num(); 70 | if(IsHopExpired(hop_num)) { 71 | TOP_WARN("Hop[%d] Is Experied.", 72 | message.hop_num()); 73 | return false; 74 | } 75 | return true; 76 | } 77 | 78 | bool RumorMessageHandler::IsHopExpired( 79 | const int32_t hop_num) const { 80 | return hop_num > max_hop_num_; 81 | } 82 | 83 | void RumorMessageHandler::HandleMessage( 84 | transport::protobuf::RoutingMessage& message, 85 | base::xpacket_t& packet) { 86 | transport::HandlerProc proc; 87 | if (!FindData(message.type(), proc)) { 88 | TOP_WARN("RumorMessageHandler::HandleMessage Failed." 89 | "Message Type[%d] does not has its proc", message.type()); 90 | return; 91 | } 92 | std::cout << "RumorMessageHandler::HandleMessage called." << std::endl; 93 | 94 | if (!CheckMessage(message.type(), message)) { 95 | TOP_WARN("RumorMessageHandler::HandleMessage Failed.Message Type Is %d", message.type()); 96 | return; 97 | } 98 | proc(message, packet); 99 | } 100 | } 101 | } 102 | -------------------------------------------------------------------------------- /tests/test_root_routing.cc: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2017-2019 Telos Foundation & contributors 2 | // Distributed under the MIT software license, see the accompanying 3 | // file COPYING or http://www.opensource.org/licenses/mit-license.php. 4 | 5 | #include 6 | 7 | #include 8 | 9 | #include 10 | 11 | #include "xpbase/base/endpoint_util.h" 12 | #include "xpbase/base/kad_key/platform_kadmlia_key.h" 13 | #define protected public 14 | #define private public 15 | #include "xtransport/udp_transport/udp_transport.h" 16 | #include "xkad/routing_table/routing_table.h" 17 | #include "xkad/routing_table/local_node_info.h" 18 | #include "xwrouter/register_routing_table.h" 19 | #include "xwrouter/root/root_routing.h" 20 | #include "xwrouter/root/root_routing_manager.h" 21 | #include "xwrouter/message_handler/wrouter_message_handler.h" 22 | #include "xtransport/message_manager/multi_message_handler.h" 23 | #include "xkad/nat_detect/nat_manager_intf.h" 24 | 25 | namespace top { 26 | 27 | namespace kadmlia { 28 | 29 | namespace test { 30 | 31 | class TestRootRouting : public testing::Test { 32 | public: 33 | static void SetUpTestCase() { 34 | } 35 | 36 | static void TearDownTestCase() { 37 | } 38 | 39 | virtual void SetUp() { 40 | base::Config config; 41 | ASSERT_TRUE(config.Init("./conf.ut/test_root.conf")); 42 | std::string local_ip; 43 | ASSERT_TRUE(config.Get("node", "local_ip", local_ip)); 44 | uint16_t local_port = 0; 45 | ASSERT_TRUE(config.Get("node", "local_port", local_port)); 46 | udp_transport_.reset(new top::transport::UdpTransport()); 47 | thread_message_handler_ = std::make_shared(); 48 | thread_message_handler_->Init(); 49 | ASSERT_TRUE(udp_transport_->Start( 50 | local_ip, 51 | local_port, 52 | thread_message_handler_.get()) == kKadSuccess); 53 | } 54 | 55 | virtual void TearDown() { 56 | ASSERT_TRUE(udp_transport_); 57 | udp_transport_->Stop(); 58 | } 59 | 60 | top::transport::UdpTransportPtr udp_transport_; 61 | std::shared_ptr thread_message_handler_; 62 | }; 63 | 64 | TEST_F(TestRootRouting, IsDestination) { 65 | wrouter::WrouterMessageHandler message_handler; 66 | std::shared_ptr root_manager; 67 | root_manager.reset(new wrouter::RootRoutingManager()); 68 | wrouter::SetRootRoutingManager(root_manager); 69 | base::Config config; 70 | ASSERT_TRUE(config.Init("./conf.ut/test_root.conf")); 71 | auto kad_key_ptr = std::make_shared(); 72 | kadmlia::NatManagerIntf::Instance()->SetNatType(kNatTypePublic); 73 | auto local_ptr = CreateLocalInfoFromConfig(config, kad_key_ptr); 74 | std::shared_ptr routing_table_ptr; 75 | routing_table_ptr.reset(new wrouter::RootRouting(udp_transport_, local_ptr)); 76 | local_ptr->set_service_type(kRoot); 77 | ASSERT_TRUE(routing_table_ptr->Init()); 78 | routing_table_ptr->bootstrap_cache_helper_->Stop(); 79 | std::set> public_endpoints_all; 80 | std::set> public_endpoints_config; 81 | std::string public_endpoints; 82 | ASSERT_TRUE(config.Get("node", "public_endpoints", public_endpoints)); 83 | top::base::ParseEndpoints(public_endpoints, public_endpoints_config); 84 | base::MergeEndpoints(public_endpoints_config, public_endpoints_all); 85 | ASSERT_FALSE(public_endpoints_all.empty()); 86 | root_manager->root_routing_map_[kRoot] = routing_table_ptr; 87 | ASSERT_EQ(routing_table_ptr->MultiJoin(public_endpoints_all), kKadSuccess); 88 | ASSERT_FALSE(routing_table_ptr->IsDestination("DDD", false)); 89 | ASSERT_FALSE(routing_table_ptr->IsDestination("DDD", true)); 90 | wrouter::SetRootRoutingManager(nullptr); 91 | } 92 | 93 | } // namespace test 94 | 95 | } // namespace kadmlia 96 | 97 | } // namespace top 98 | -------------------------------------------------------------------------------- /tests/test_multi_routing.cc: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2017-2019 Telos Foundation & contributors 2 | // Distributed under the MIT software license, see the accompanying 3 | // file COPYING or http://www.opensource.org/licenses/mit-license.php. 4 | 5 | #include 6 | 7 | #include 8 | 9 | #include "xpbase/base/top_utils.h" 10 | #include "xpbase/base/line_parser.h" 11 | #include "xpbase/base/check_cast.h" 12 | #include "xpbase/base/xid/xid_def.h" 13 | #include "xpbase/base/xid/xid_generator.h" 14 | #include "xpbase/base/kad_key/platform_kadmlia_key.h" 15 | #define private public 16 | #include "xtransport/udp_transport/udp_transport.h" 17 | #include "xtransport/message_manager/multi_message_handler.h" 18 | #include "xkad/routing_table/routing_table.h" 19 | #include "xkad/routing_table/local_node_info.h" 20 | #include "xwrouter/multi_routing/multi_routing.h" 21 | #include "xwrouter/register_routing_table.h" 22 | 23 | namespace top { 24 | 25 | namespace kadmlia { 26 | 27 | namespace test { 28 | 29 | class TestMultiRouting : public testing::Test { 30 | public: 31 | enum TestRoutingType { 32 | 33 | }; 34 | static void SetUpTestCase() { 35 | } 36 | 37 | static void TearDownTestCase() { 38 | } 39 | 40 | virtual void SetUp() { 41 | } 42 | 43 | virtual void TearDown() { 44 | } 45 | 46 | RoutingTablePtr CreateRoutingTable(const std::string& peer) { 47 | std::string idtype(top::kadmlia::GenNodeIdType("CN", "VPN")); 48 | LocalNodeInfoPtr local_node_info; 49 | local_node_info.reset(new LocalNodeInfo()); 50 | /* 51 | auto xip_ptr = std::make_shared(); 52 | base::XIDSptr xid = nullptr; 53 | xid.reset(new base::XID); 54 | base::XIDGenerator xid_generator; 55 | xid_generator.GetXID(*xid); 56 | */ 57 | auto kad_key = std::make_shared(); 58 | kad_key->set_xnetwork_id(kEdgeXVPN); 59 | kad_key->set_zone_id(check_cast(26)); 60 | local_node_info->Init( 61 | "0.0.0.0", 0, false, false, idtype, kad_key, kad_key->xnetwork_id(), kRoleEdge); 62 | local_node_info->set_public_ip("127.0.0.1"); 63 | local_node_info->set_public_port(10000); 64 | 65 | top::transport::TransportPtr udp_transport; 66 | udp_transport.reset(new top::transport::UdpTransport()); 67 | auto thread_message_handler = std::make_shared(); 68 | thread_message_handler->Init(); 69 | udp_transport->Start( 70 | "0.0.0.0", 71 | 0, 72 | thread_message_handler.get()); 73 | 74 | RoutingTablePtr routing_table_ptr; 75 | routing_table_ptr.reset(new top::kadmlia::RoutingTable( 76 | udp_transport, kNodeIdSize, local_node_info)); 77 | std::string bootstrap_path = "../../conf.ut/bootstrap.data"; 78 | top::wrouter::UnregisterRoutingTable(100); 79 | top::wrouter::RegisterRoutingTable(100, routing_table_ptr); 80 | top::base::LineParser line_split(peer.c_str(), ':', peer.size()); 81 | std::set> boot_endpoints{ 82 | { line_split[0], check_cast(line_split[1]) } 83 | }; 84 | // int res = routing_table_ptr->MultiJoin(line_split[0], check_cast(line_split[1])); 85 | // ASSERT_EQ(res, kKadSuccess); 86 | // ASSERT_TRUE(routing_table_ptr->joined_); 87 | return routing_table_ptr; 88 | } 89 | }; 90 | 91 | TEST_F(TestMultiRouting, AddRoutingTable) { 92 | wrouter::MultiRouting multi_routing; 93 | RoutingTablePtr routing_table1 = CreateRoutingTable("10.88.0.101:9901"); 94 | multi_routing.AddRoutingTable(100, routing_table1); 95 | RoutingTablePtr routing_table2 = CreateRoutingTable("10.88.0.101:9902"); 96 | multi_routing.AddRoutingTable(101, routing_table2); 97 | } 98 | 99 | } // namespace test 100 | 101 | } // namespace kadmlia 102 | 103 | } // namespace top 104 | -------------------------------------------------------------------------------- /message_handler/xwrouter_xid_handler.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2017-2019 Telos Foundation & contributors 2 | // Distributed under the MIT software license, see the accompanying 3 | // file COPYING or http://www.opensource.org/licenses/mit-license.php. 4 | 5 | #pragma once 6 | 7 | #include 8 | 9 | #include "xwrouter/message_handler/xwrouter_handler.h" 10 | #include "xkad/routing_table/callback_manager.h" 11 | #include "xwrouter/wrouter_utils/wrouter_utils.h" 12 | #include "xbase/xbase.h" 13 | #include "xbase/xrouter.h" 14 | #include "xgossip/include/broadcast_layered.h" 15 | 16 | namespace top { 17 | 18 | namespace transport { 19 | class MultiThreadHandler; 20 | class Transport; 21 | typedef std::shared_ptr TransportPtr; 22 | 23 | namespace protobuf { 24 | class RoutingMessage; 25 | }; 26 | }; 27 | 28 | namespace base { 29 | class XipParser; 30 | }; 31 | 32 | namespace kadmlia { 33 | class RoutingTable; 34 | struct NodeInfo; 35 | typedef std::shared_ptr RoutingTablePtr; 36 | typedef std::shared_ptr NodeInfoPtr; 37 | }; 38 | 39 | namespace gossip { 40 | class GossipInterface; 41 | } 42 | 43 | namespace wrouter { 44 | 45 | using Xip2Header = _xip2_header; 46 | 47 | class WrouterXidHandler : public WrouterHandler { 48 | public: 49 | WrouterXidHandler( 50 | transport::TransportPtr transport_ptr, 51 | std::shared_ptr bloom_gossip_ptr, 52 | std::shared_ptr layered_gossip_ptr, 53 | std::shared_ptr bloom_layer_gossip_ptr, 54 | std::shared_ptr set_layer_gossip_ptr); 55 | 56 | ~WrouterXidHandler(); 57 | public: 58 | virtual int32_t SendPacket(transport::protobuf::RoutingMessage& message) override; 59 | virtual int32_t RecvPacket( 60 | transport::protobuf::RoutingMessage& message, 61 | base::xpacket_t& packet); 62 | int32_t SendToLocal(transport::protobuf::RoutingMessage& message); 63 | int32_t SendDirect( 64 | transport::protobuf::RoutingMessage& message, 65 | const std::string& ip, 66 | uint16_t port); 67 | void SupportRandomPattern(); 68 | bool BroadcastByMultiRandomKadKey( 69 | const transport::protobuf::RoutingMessage& message, 70 | kadmlia::ResponseFunctor call_back, 71 | int64_t recursive_count = kRecursiveCount); 72 | protected: 73 | uint64_t ParserServiceType(const std::string& kad_key); 74 | bool SendToByRandomNeighbors( 75 | const transport::protobuf::RoutingMessage& message); 76 | int32_t RandomlyCommunicate( 77 | transport::protobuf::RoutingMessage& message); 78 | void SendLinksAckToPeer( 79 | uint64_t src_message_id, 80 | const std::string& src_node_id, 81 | const std::string& peer_ip, 82 | uint16_t peer_port, 83 | uint64_t ack_type); 84 | 85 | bool MulticastPacketCheck(transport::protobuf::RoutingMessage& message); 86 | bool GossipPacketCheck(transport::protobuf::RoutingMessage& message); 87 | 88 | int32_t SendMulticast(transport::protobuf::RoutingMessage& message); 89 | int32_t SendGossip(transport::protobuf::RoutingMessage& message); 90 | int32_t SendGeneral(transport::protobuf::RoutingMessage& message); 91 | 92 | // judge packet arrive the dest or not 93 | int32_t JudgeOwnPacket( 94 | transport::protobuf::RoutingMessage& message, 95 | base::xpacket_t& packet); 96 | 97 | int32_t GossipBroadcast( 98 | transport::protobuf::RoutingMessage& message, 99 | kadmlia::RoutingTablePtr& routing_table); 100 | int32_t SendData( 101 | transport::protobuf::RoutingMessage& message, 102 | const std::vector& neighbors, 103 | uint32_t next_size, 104 | bool broadcast_stride); 105 | int32_t HandleClientMessage( 106 | transport::protobuf::RoutingMessage& message, 107 | kadmlia::RoutingTablePtr routing_table); 108 | bool HandleSystemMessage( 109 | transport::protobuf::RoutingMessage& message, 110 | kadmlia::RoutingTablePtr& routing_table); 111 | 112 | private: 113 | bool support_random_pattern_ {false}; 114 | 115 | DISALLOW_COPY_AND_ASSIGN(WrouterXidHandler); 116 | }; 117 | 118 | } // namespace wrouter 119 | 120 | } // namespace top 121 | -------------------------------------------------------------------------------- /src/small_net_cache.cc: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2017-2019 Telos Foundation & contributors 2 | // Distributed under the MIT software license, see the accompanying 3 | // file COPYING or http://www.opensource.org/licenses/mit-license.php. 4 | 5 | #include "xwrouter/multi_routing/small_net_cache.h" 6 | 7 | #include 8 | 9 | #include "xpbase/base/top_log.h" 10 | #include "xpbase/base/top_timer.h" 11 | #include "xpbase/base/kad_key/kadmlia_key.h" 12 | #include "xpbase/base/kad_key/get_kadmlia_key.h" 13 | #include "xpbase/base/xip_parser.h" 14 | 15 | namespace top { 16 | 17 | namespace wrouter { 18 | static const uint32_t kElectNodesExpirePeriod = 20 * 60 * 1000; // 20 min 19 | static const uint64_t kClearPeriod = 5l * 60ll * 1000ll * 1000ll; // 5 min check timer 20 | 21 | SmallNetNodes* SmallNetNodes::Instance() { 22 | static SmallNetNodes ins; 23 | return &ins; 24 | } 25 | 26 | bool SmallNetNodes::Init() { 27 | clear_timer_ = std::make_shared(base::TimerManager::Instance(), "SmallNetNodes::Clear"); 28 | clear_timer_->Start( 29 | 500ll * 1000ll, 30 | kClearPeriod, 31 | std::bind(&SmallNetNodes::do_clear_and_reset, this)); 32 | return true; 33 | } 34 | 35 | SmallNetNodes::SmallNetNodes() { 36 | } 37 | 38 | SmallNetNodes::~SmallNetNodes() { 39 | clear_timer_->Join(); 40 | clear_timer_ = nullptr; 41 | } 42 | 43 | bool SmallNetNodes::FindNode(const std::string& account, NetNode& Fnode) { 44 | std::unique_lock lock(net_nodes_cache_map_mutex_); 45 | for (auto mitem : net_nodes_cache_map_) { 46 | for (auto& item : mitem.second) { 47 | if (item.m_account == account) { 48 | Fnode = item; 49 | return true; 50 | } 51 | } 52 | } 53 | TOP_WARN("findnode of account:%s failed", account.c_str()); 54 | return false; 55 | } 56 | 57 | bool SmallNetNodes::FindNode(uint32_t index, NetNode& Fnode, uint64_t service_type) { 58 | std::unique_lock lock(net_nodes_cache_map_mutex_); 59 | auto ifind = net_nodes_cache_map_.find(service_type); 60 | if (ifind == net_nodes_cache_map_.end()) { 61 | return false; 62 | } 63 | auto size = (ifind->second).size(); 64 | if ( size <= index) { 65 | TOP_WARN("index:%d beyond vector.size:%d", index, size); 66 | return false; 67 | } 68 | 69 | Fnode = (ifind->second)[index]; 70 | TOP_DEBUG("findnode of index:%d account:%s", index, Fnode.m_account.c_str()); 71 | return true; 72 | } 73 | 74 | bool SmallNetNodes::FindRandomNode(NetNode& Fnode, uint64_t service_type) { 75 | std::unique_lock lock(net_nodes_cache_map_mutex_); 76 | auto ifind = net_nodes_cache_map_.find(service_type); 77 | if (ifind == net_nodes_cache_map_.end()) { 78 | return false; 79 | } 80 | 81 | auto size = (ifind->second).size(); 82 | if (size == 0) { 83 | return false; 84 | } 85 | uint32_t index = RandomUint32() % size; 86 | Fnode = ifind->second[index]; 87 | TOP_DEBUG("findnode of index:%d account:%s", index, Fnode.m_account.c_str()); 88 | return true; 89 | } 90 | 91 | bool SmallNetNodes::FindAllNode(std::vector& node_vec ,uint64_t service_type) { 92 | std::unique_lock lock(net_nodes_cache_map_mutex_); 93 | auto ifind = net_nodes_cache_map_.find(service_type); 94 | if (ifind == net_nodes_cache_map_.end()) { 95 | return false; 96 | } 97 | node_vec = ifind->second; 98 | return true; 99 | } 100 | 101 | uint32_t SmallNetNodes::AddNode(NetNode node) { 102 | std::unique_lock lock(net_nodes_cache_map_mutex_); 103 | base::KadmliaKeyPtr kad_key = GetKadmliaKey(node.m_xip); 104 | uint64_t service_type = kad_key->GetServiceType(); 105 | net_nodes_cache_map_[service_type].push_back(node); 106 | TOP_DEBUG("addnode account:%s public_key:%s xip:%s", 107 | node.m_account.c_str(), 108 | node.m_public_key.c_str(), 109 | HexEncode(node.m_xip.xip()).c_str()); 110 | return net_nodes_cache_map_[service_type].size(); 111 | } 112 | 113 | void SmallNetNodes::do_clear_and_reset() { 114 | std::unique_lock lock(net_nodes_cache_map_mutex_); 115 | auto now = std::chrono::steady_clock::now(); 116 | for (auto& mitem: net_nodes_cache_map_) { 117 | for (auto iter = (mitem.second).begin(); iter != (mitem.second).end(); ) { 118 | if (now - std::chrono::milliseconds(kElectNodesExpirePeriod) > (*iter).time_point) { 119 | // elect nodes expired 120 | iter = (mitem.second).erase(iter); 121 | TOP_INFO("elect node:%s expired from SmallNet", (*iter).m_account.c_str()); 122 | } else { 123 | ++ iter; 124 | } 125 | } 126 | } 127 | } 128 | 129 | } // end namespace wrouter 130 | 131 | } // end namespace top 132 | -------------------------------------------------------------------------------- /demo/demo_routing.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2017-2019 Telos Foundation & contributors 2 | // Distributed under the MIT software license, see the accompanying 3 | // file COPYING or http://www.opensource.org/licenses/mit-license.php. 4 | 5 | #pragma once 6 | 7 | #include 8 | 9 | #include "xpbase/base/top_config.h" 10 | #include "xpbase/base/top_utils.h" 11 | #include "xpbase/base/xip_parser.h" 12 | #include "xpbase/base/top_timer.h" 13 | #include "xkad/routing_table/routing_table.h" 14 | #include "xkad/routing_table/node_info.h" 15 | #include "xwrouter/root/root_message_handler.h" 16 | #include "xwrouter/wrouter_utils/wrouter_utils.h" 17 | #include "xwrouter/wrouter_utils/wrouter_base_routing.h" 18 | 19 | namespace top { 20 | 21 | class DemoRouting : public wrouter::WrouterBaseRouting { 22 | public: 23 | DemoRouting( 24 | std::shared_ptr transport, 25 | kadmlia::LocalNodeInfoPtr local_node_ptr, 26 | const uint32_t RoutingMaxNodesSize); 27 | virtual ~DemoRouting() override; 28 | 29 | protected: 30 | virtual bool NewNodeReplaceOldNode(kadmlia::NodeInfoPtr node, bool remove) override; 31 | virtual uint32_t GetFindNodesMaxSize() override; 32 | private: 33 | uint32_t RoutingMaxNodesSize_ {128}; 34 | }; 35 | 36 | 37 | DemoRouting::DemoRouting( 38 | std::shared_ptr transport, 39 | kadmlia::LocalNodeInfoPtr local_node_ptr, 40 | const uint32_t RoutingMaxNodesSize) 41 | : RoutingMaxNodesSize_(RoutingMaxNodesSize), 42 | wrouter::WrouterBaseRouting(transport, kNodeIdSize, local_node_ptr) {} 43 | 44 | DemoRouting::~DemoRouting() {} 45 | 46 | bool DemoRouting::NewNodeReplaceOldNode(top::kadmlia::NodeInfoPtr node, bool remove) { 47 | const auto max_count = RoutingMaxNodesSize_; 48 | // const auto max_count = 16; // for test 49 | if (nodes_.size() < max_count) { 50 | return true; 51 | } 52 | 53 | std::map bucket_rank_map; 54 | unsigned int max_bucket(-1), max_bucket_count(0); 55 | std::for_each( 56 | std::begin(nodes_), 57 | std::end(nodes_), 58 | [&bucket_rank_map, &max_bucket, &max_bucket_count, node](const top::kadmlia::NodeInfoPtr & node_info) { 59 | bucket_rank_map[node_info->bucket_index] += 1; 60 | 61 | if (bucket_rank_map[node_info->bucket_index] >= max_bucket_count) { 62 | max_bucket = node_info->bucket_index; 63 | max_bucket_count = bucket_rank_map[node_info->bucket_index]; 64 | } 65 | }); 66 | 67 | // not satisfy replacing 68 | // if (max_bucket_count <= kKadParamK) { 69 | // // first node in empty k-bucket, add directly 70 | // if (bucket_rank_map[node->bucket_index] < kKadParamK) { 71 | // TOP_DEBUG_NAME(""); 72 | // return true; 73 | // } 74 | 75 | // // no replace 76 | // TOP_DEBUG_NAME(""); 77 | // return false; 78 | // } 79 | 80 | // dump all nodes 81 | // { 82 | // std::string fmt("all nodes:\n"); 83 | // for (int i = 0; i < nodes_.size(); ++i) { 84 | // // fmt += base::StringUtil::str_fmt("%d: count(%d)\n", kv.first, kv.second); 85 | // fmt += base::StringUtil::str_fmt("%3d]: %s, %s:%d, dis(%d)\n", (int)i, HexSubstr(nodes_[i]->node_id).c_str(), 86 | // nodes_[i]->public_ip.c_str(), (int)nodes_[i]->public_port, nodes_[i]->bucket_index); 87 | // } 88 | // TOP_DEBUG_NAME("%s", fmt.c_str()); 89 | // } 90 | 91 | // replace node 92 | for (auto it(nodes_.rbegin()); it != nodes_.rend(); ++it) { 93 | if (static_cast((*it)->bucket_index) != max_bucket || 94 | node->bucket_index == (*it)->bucket_index) { 95 | continue; 96 | } 97 | 98 | const bool very_less = bucket_rank_map[node->bucket_index] < bucket_rank_map[(*it)->bucket_index] - 1; 99 | const bool less_and_closer = bucket_rank_map[node->bucket_index] < bucket_rank_map[(*it)->bucket_index] 100 | && node->bucket_index < (*it)->bucket_index; 101 | const bool empty_and_closer = bucket_rank_map[node->bucket_index] == 0 102 | && node->bucket_index < (*it)->bucket_index; 103 | if (very_less || less_and_closer || empty_and_closer) { 104 | if (!remove) { 105 | return true; 106 | } 107 | { 108 | std::unique_lock set_lock(node_id_map_mutex_); 109 | auto id_map_iter = node_id_map_.find((*it)->node_id); 110 | if (id_map_iter != node_id_map_.end()) { 111 | node_id_map_.erase(id_map_iter); 112 | } 113 | } 114 | nodes_.erase(--(it.base())); 115 | { 116 | std::unique_lock lock_hash(node_hash_map_mutex_); 117 | auto hash_iter = node_hash_map_->find((*it)->hash64); 118 | if (hash_iter != node_hash_map_->end()) { 119 | node_hash_map_->erase(hash_iter); 120 | } 121 | } 122 | return true; 123 | } // end if (replace... 124 | } // end for 125 | 126 | return false; 127 | 128 | } 129 | 130 | uint32_t DemoRouting::GetFindNodesMaxSize() { 131 | return RoutingMaxNodesSize_; 132 | } 133 | } 134 | -------------------------------------------------------------------------------- /src/xwrouter_handler.cc: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2017-2019 Telos Foundation & contributors 2 | // Distributed under the MIT software license, see the accompanying 3 | // file COPYING or http://www.opensource.org/licenses/mit-license.php. 4 | 5 | #include "xwrouter/message_handler/xwrouter_handler.h" 6 | 7 | #include 8 | 9 | #include "xpbase/base/kad_key/get_kadmlia_key.h" 10 | #include "xpbase/base/xip_parser.h" 11 | #include "xpbase/base/kad_key/platform_kadmlia_key.h" 12 | #include "xkad/routing_table/routing_table.h" 13 | #include "xkad/routing_table/routing_utils.h" 14 | #include "xwrouter/register_routing_table.h" 15 | #include "xwrouter/message_handler/wrouter_message_handler.h" 16 | #include "xpbase/base/xip_parser.h" 17 | #include "xpbase/base/top_utils.h" 18 | #include "xkad/routing_table/client_node_manager.h" 19 | #include "xkad/routing_table/dynamic_xip_manager.h" 20 | #include "xtransport/utils/transport_utils.h" 21 | #include "xpbase/base/kad_key/get_kadmlia_key.h" 22 | #include "xpbase/base/uint64_bloomfilter.h" 23 | #include "xpbase/base/redis_client.h" 24 | #include "xkad/gossip/rumor_filter.h" 25 | #include "xgossip/include/broadcast_layered.h" 26 | #include "xgossip/include/gossip_bloomfilter.h" 27 | #include "xgossip/include/gossip_bloomfilter_layer.h" 28 | #include "xgossip/include/gossip_utils.h" 29 | #include "xgossip/gossip_interface.h" 30 | #include "xpbase/base/top_log.h" 31 | #include "xbase/xutl.h" 32 | #include "xtransport/message_manager/message_manager_intf.h" 33 | 34 | namespace top { 35 | 36 | using namespace kadmlia; 37 | using namespace gossip; 38 | 39 | namespace wrouter { 40 | 41 | WrouterHandler::WrouterHandler( 42 | transport::TransportPtr transport_ptr, 43 | std::shared_ptr bloom_gossip_ptr, 44 | std::shared_ptr layered_gossip_ptr, 45 | std::shared_ptr bloom_layer_gossip_ptr, 46 | std::shared_ptr set_layer_gossip_ptr) 47 | : transport_ptr_(transport_ptr), 48 | bloom_gossip_ptr_(bloom_gossip_ptr), 49 | layered_gossip_ptr_(layered_gossip_ptr), 50 | bloom_layer_gossip_ptr_(bloom_layer_gossip_ptr), 51 | set_layer_gossip_ptr_(set_layer_gossip_ptr) {} 52 | 53 | 54 | WrouterHandler::~WrouterHandler() { 55 | transport_ptr_ = nullptr; 56 | bloom_gossip_ptr_ = nullptr; 57 | layered_gossip_ptr_ = nullptr; 58 | bloom_layer_gossip_ptr_ = nullptr; 59 | set_layer_gossip_ptr_ = nullptr; 60 | } 61 | 62 | kadmlia::RoutingTablePtr WrouterHandler::FindRoutingTable( 63 | bool is_root, 64 | uint64_t service_type, 65 | bool root_backup, 66 | const std::string msg_des_node_id) { 67 | // TODO(smaug) GetSmartRoutingTable 68 | RoutingTablePtr routing_table = GetRoutingTable(service_type, is_root); 69 | if (routing_table) { 70 | return routing_table; 71 | } 72 | if (!root_backup) { 73 | return nullptr; 74 | } 75 | 76 | // using backup, should choose the right root-routing-table 77 | std::vector vec_type; 78 | GetAllRegisterType(vec_type); 79 | auto tmp_routing_table1 = GetRoutingTable(kRoot, true); 80 | auto target_routing_table = tmp_routing_table1; 81 | if (tmp_routing_table1) { 82 | std::string tmp_id1 = tmp_routing_table1->get_local_node_info()->id(); 83 | for (auto& tmp_service_type : vec_type) { 84 | auto tmp_routing_table2 = GetRoutingTable(tmp_service_type, true); 85 | if (!tmp_routing_table2) { 86 | TOP_WARN2("GetRoutingTable %llu empty", tmp_service_type); 87 | continue; 88 | } 89 | std::string tmp_id2 = tmp_routing_table2->get_local_node_info()->id(); 90 | if (!CloserToTarget(tmp_id1, tmp_id2, msg_des_node_id)) { 91 | tmp_id1 = tmp_id2; 92 | tmp_routing_table1 = tmp_routing_table2; 93 | } 94 | } // end for 95 | target_routing_table = tmp_routing_table1; 96 | } 97 | 98 | if (target_routing_table) { 99 | return target_routing_table; 100 | } 101 | 102 | if (vec_type.empty()) { 103 | return nullptr; 104 | } 105 | // no dest routing_table and no root routing_table, choose anyone(usually this is client) 106 | return GetRoutingTable(vec_type[0], false); 107 | } 108 | 109 | std::vector WrouterHandler::GetClosestNodes( 110 | kadmlia::RoutingTablePtr routing_table, 111 | const std::string& target_id, 112 | uint32_t number_to_get, 113 | bool base_xip) { 114 | if (!routing_table) { 115 | return {}; 116 | } 117 | // TODO(smaug) judge node quality good or not good 118 | return routing_table->GetClosestNodes(target_id, number_to_get, base_xip); 119 | } 120 | 121 | std::vector WrouterHandler::GetRandomNodes ( 122 | std::vector& neighbors, 123 | uint32_t number_to_get) const { 124 | if(neighbors.size() <= number_to_get) { 125 | return neighbors; 126 | } 127 | std::random_shuffle(neighbors.begin(),neighbors.end()); 128 | return std::vector {neighbors.begin(),neighbors.begin() + number_to_get}; 129 | } 130 | 131 | bool WrouterHandler::CloserToTarget( 132 | const std::string& id1, 133 | const std::string& id2, 134 | const std::string& target_id) { 135 | for (int i = 0; i < top::kNodeIdSize; ++i) { 136 | unsigned char result1 = id1[i] ^ target_id[i]; 137 | unsigned char result2 = id2[i] ^ target_id[i]; 138 | if (result1 != result2) { 139 | return result1 < result2; 140 | } 141 | } 142 | return false; 143 | } 144 | 145 | } // namespace wrouter 146 | 147 | } // namespace top 148 | -------------------------------------------------------------------------------- /message_handler/wrouter_message_handler.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2017-2019 Telos Foundation & contributors 2 | // Distributed under the MIT software license, see the accompanying 3 | // file COPYING or http://www.opensource.org/licenses/mit-license.php. 4 | 5 | #pragma once 6 | 7 | #include 8 | #include 9 | #include 10 | 11 | #include "xbase/xlog.h" 12 | #include "xbase/xobject.h" 13 | #include "xbase/xthread.h" 14 | #include "xbase/xtimer.h" 15 | #include "xbase/xdata.h" 16 | #include "xbase/xpacket.h" 17 | #include "xbase/xsocket.h" 18 | #include "xbase/xutl.h" 19 | 20 | #include "xkad/proto/kadmlia.pb.h" 21 | #include "xwrouter/wrouter_utils/wrouter_utils.h" 22 | #include "xwrouter/register_message_handler.h" 23 | #include "xtransport/message_manager/message_manager_intf.h" 24 | #include "xkad/nat_detect/nat_manager_intf.h" 25 | 26 | namespace top { 27 | 28 | namespace kadmlia { 29 | class RoutingTable; 30 | class ThreadHandler; 31 | } 32 | 33 | namespace wrouter { 34 | class Wrouter; 35 | 36 | 37 | static const int32_t MsgHandlerMaxSize = 4096; 38 | using ArrayHandlers = std::array; 39 | using MapRequestType = std::map; 40 | 41 | class WrouterMessageHandler { 42 | private: 43 | friend class Wrouter; 44 | friend class ThreadHandler; 45 | friend void WrouterRegisterMessageHandler(int msg_type, transport::HandlerProc handler_proc); 46 | friend void WrouterUnregisterMessageHandler(int msg_type); 47 | 48 | friend void WrouterRegisterMessageRequestType(int msg_type, int request_type); 49 | friend void WrouterUnregisterMessageRequestType(int msg_type); 50 | friend int WrouterGetRequestType(int msg_type); 51 | friend void WrouterSelfHandleMessage( 52 | transport::protobuf::RoutingMessage& message, 53 | base::xpacket_t& packet); 54 | 55 | static WrouterMessageHandler* Instance(); 56 | void HandleMessage( 57 | transport::protobuf::RoutingMessage& message, 58 | base::xpacket_t& packet); 59 | 60 | void HandleSyncMessage( 61 | transport::protobuf::RoutingMessage& message, 62 | base::xpacket_t& packet); 63 | void AddHandler(int msg_type, transport::HandlerProc handler_proc); 64 | void AddRequestType(int msg_type, int request_type); 65 | //bool FindHandler(int msg_type, HandlerProc& handler_proc) const; 66 | int GetRequestType(int msg_type); 67 | void RemoveHandler(int msg_type); 68 | void RemoveRequestType(int msg_type); 69 | int SendData( 70 | const transport::protobuf::RoutingMessage& message, 71 | const std::string& peer_ip, 72 | uint16_t peer_port); 73 | 74 | WrouterMessageHandler(); 75 | ~WrouterMessageHandler(); 76 | void AddBaseHandlers(); 77 | 78 | void CheckBitVPNClientMessage(transport::protobuf::RoutingMessage& message); 79 | void CheckNatDetectMessage(transport::protobuf::RoutingMessage& message); 80 | int HandleClientMessage( 81 | transport::protobuf::RoutingMessage& message, 82 | base::xpacket_t& packet); 83 | int HandleMultiRelayMessage( 84 | transport::protobuf::RoutingMessage& message, 85 | base::xpacket_t& packet); 86 | bool CheckMultiRelay(transport::protobuf::RoutingMessage& message); 87 | std::shared_ptr MultiRelayGetSmartRoutingTable( 88 | transport::protobuf::RoutingMessage& message); 89 | int HandleMultiRelayMessageSpearHead( 90 | transport::protobuf::RoutingMessage& message, 91 | base::xpacket_t& packet); 92 | int CheckRelayMsgToNextEdgeNetwork(transport::protobuf::RoutingMessage& message); 93 | void RelayMsgToNextEdgeNetwork(transport::protobuf::RoutingMessage& message); 94 | void RelayMsgToNextServiceNetwork( 95 | transport::protobuf::RoutingMessage& message, 96 | std::shared_ptr routing_table); 97 | 98 | void SendMultiRelayResponse(transport::protobuf::RoutingMessage& message); 99 | int HandleMultiRelayRequest( 100 | transport::protobuf::RoutingMessage& message, 101 | base::xpacket_t& packet); 102 | 103 | void CallbackMultiRelayResponse(transport::protobuf::RoutingMessage& message); 104 | int HandleMultiRelayResponse( 105 | transport::protobuf::RoutingMessage& message, 106 | base::xpacket_t& packet); 107 | 108 | void PrintRelayHopInfo(transport::protobuf::RoutingMessage& message); 109 | void PrintTraceRoute(transport::protobuf::RoutingMessage& message); 110 | 111 | void HandleConnectRequest( 112 | transport::protobuf::RoutingMessage& message, 113 | base::xpacket_t& packet); 114 | void HandleHandshake(transport::protobuf::RoutingMessage& message, base::xpacket_t& packet); 115 | void HandleBootstrapJoinRequest( 116 | transport::protobuf::RoutingMessage& message, 117 | base::xpacket_t& packet); 118 | void HandleBootstrapJoinResponse( 119 | transport::protobuf::RoutingMessage& message, 120 | base::xpacket_t& packet); 121 | void HandleFindNodesRequest( 122 | transport::protobuf::RoutingMessage& message, 123 | base::xpacket_t& packet); 124 | void HandleFindNodesResponse( 125 | transport::protobuf::RoutingMessage& message, 126 | base::xpacket_t& packet); 127 | void SendAck( 128 | transport::protobuf::RoutingMessage& message, 129 | base::xpacket_t& packet); 130 | void HandleHeartbeatRequest( 131 | transport::protobuf::RoutingMessage& message, 132 | base::xpacket_t& packet); 133 | void HandleHeartbeatResponse( 134 | transport::protobuf::RoutingMessage& message, 135 | base::xpacket_t& packet); 136 | void HandleNodeQuit( 137 | transport::protobuf::RoutingMessage& message, 138 | base::xpacket_t& packet); 139 | 140 | // test multi relay message 141 | void HandleTestMultiRelayRequest( 142 | transport::protobuf::RoutingMessage& message, 143 | base::xpacket_t& packet); 144 | void HandleTestMultiRelayResponse( 145 | transport::protobuf::RoutingMessage& message, 146 | base::xpacket_t& packet); 147 | void HandleBroadcastFromMultiChannelRequest( 148 | transport::protobuf::RoutingMessage& message, 149 | base::xpacket_t& packet); 150 | void HandleBroadcastFromMultiChannelAck( 151 | transport::protobuf::RoutingMessage& message, 152 | base::xpacket_t& packet); 153 | void HandleSendToFromRandomNeighborsRequest( 154 | transport::protobuf::RoutingMessage& message, 155 | base::xpacket_t& packet); 156 | 157 | ArrayHandlers array_handlers_; 158 | std::mutex map_request_type_mutex_; 159 | std::map map_request_type_; 160 | transport::MessageManagerIntf* message_manager_{transport::MessageManagerIntf::Instance()}; 161 | kadmlia::NatManagerIntf* nat_manager_{kadmlia::NatManagerIntf::Instance()}; 162 | }; 163 | 164 | typedef std::shared_ptr MessageHandlerPtr; 165 | 166 | } // namespace wrouter 167 | 168 | } // namespace top 169 | -------------------------------------------------------------------------------- /src/register_routing_table.cc: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2017-2019 Telos Foundation & contributors 2 | // Distributed under the MIT software license, see the accompanying 3 | // file COPYING or http://www.opensource.org/licenses/mit-license.php. 4 | 5 | #include "xwrouter/register_routing_table.h" 6 | 7 | #include "xwrouter/multi_routing/multi_routing.h" 8 | #include "xkad/routing_table/local_node_info.h" 9 | #include "xwrouter/root/root_routing_manager.h" 10 | #include "xwrouter/root/root_routing.h" 11 | 12 | namespace top { 13 | 14 | using namespace kadmlia; 15 | 16 | namespace wrouter { 17 | 18 | void RegisterRoutingTable(uint64_t type, std::shared_ptr routing_table) { 19 | TOP_INFO("register routing table %llu", type); 20 | MultiRouting::Instance()->AddRoutingTable(type, routing_table); 21 | } 22 | 23 | void UnregisterRoutingTable(uint64_t type) { 24 | TOP_INFO("unregister routing table %llu", type); 25 | MultiRouting::Instance()->RemoveRoutingTable(type); 26 | } 27 | 28 | void UnregisterAllRoutingTable() { 29 | TOP_INFO("unregister allrouting table"); 30 | MultiRouting::Instance()->RemoveAllRoutingTable(); 31 | } 32 | 33 | void SetRootRoutingManager(std::shared_ptr root_manager_ptr) { 34 | MultiRouting::Instance()->SetRootRoutingManager(root_manager_ptr); 35 | } 36 | 37 | std::shared_ptr GetRoutingTable(const uint64_t& type, bool root) { 38 | RoutingTablePtr routing_table = MultiRouting::Instance()->GetRoutingTable(type, root); 39 | if (routing_table) { 40 | return routing_table; 41 | } 42 | return nullptr; 43 | } 44 | 45 | std::shared_ptr GetRoutingTable(const std::string& routing_id, bool root) { 46 | RoutingTablePtr routing_table = MultiRouting::Instance()->GetRoutingTable(routing_id, root); 47 | if (routing_table) { 48 | return routing_table; 49 | } 50 | return nullptr; 51 | } 52 | 53 | void GetAllRegisterType(std::vector& vec_type) { 54 | return MultiRouting::Instance()->GetAllRegisterType(vec_type); 55 | } 56 | 57 | bool CheckTypeExist(uint64_t type) { 58 | return MultiRouting::Instance()->CheckTypeExist(type); 59 | } 60 | 61 | std::shared_ptr GetSmartRoutingTable(uint64_t type) { 62 | return MultiRouting::Instance()->GetSmartRoutingTable(type); 63 | } 64 | 65 | uint64_t TryGetSmartRoutingTable(uint64_t type) { 66 | return MultiRouting::Instance()->TryGetSmartRoutingTable(type); 67 | } 68 | 69 | bool SetCacheServiceType(uint64_t service_type) { 70 | return MultiRouting::Instance()->SetCacheServiceType(service_type); 71 | } 72 | 73 | bool GetServiceBootstrapRootNetwork( 74 | uint64_t service_type, 75 | std::set>& boot_endpoints) { 76 | return MultiRouting::Instance()->GetServiceBootstrapRootNetwork(service_type, boot_endpoints); 77 | } 78 | 79 | int NetworkExists( 80 | base::KadmliaKeyPtr& kad_key_ptr, 81 | std::set>& endpoints) { 82 | auto root_routing = std::dynamic_pointer_cast(GetRoutingTable(kRoot, true)); 83 | if (!root_routing) { 84 | TOP_ERROR("create root manager failed!"); 85 | return kadmlia::kKadFailed; 86 | } 87 | 88 | uint64_t init_service_type = kad_key_ptr->GetServiceType(); 89 | std::vector tmp_nodes; 90 | if (root_routing->GetRootNodes( 91 | kad_key_ptr->Get(), 92 | tmp_nodes) != kadmlia::kKadSuccess) { 93 | TOP_WARN("GetRootNodes by root routing failed"); 94 | return kadmlia::kKadFailed; 95 | } 96 | TOP_INFO("GetRootNodes by root routing ok."); 97 | 98 | for (uint32_t i = 0; i < tmp_nodes.size(); ++i) { 99 | auto tmp_kad_key = base::GetKadmliaKey(tmp_nodes[i]->node_id); 100 | uint64_t node_service_type = tmp_kad_key->GetServiceType(); 101 | if (init_service_type != node_service_type) { 102 | continue; 103 | } 104 | if (tmp_nodes[i]->IsPublicNode()) { 105 | endpoints.insert(std::make_pair( 106 | tmp_nodes[i]->public_ip, 107 | tmp_nodes[i]->public_port)); 108 | } 109 | } 110 | if (!endpoints.empty()) { 111 | TOP_INFO("GetRootNodes from remote ok, size:%d", endpoints.size()); 112 | return kadmlia::kKadSuccess; 113 | } 114 | return kadmlia::kKadFailed; 115 | } 116 | 117 | int GetSameNetworkPublicEndpoints( 118 | base::KadmliaKeyPtr& kad_key_ptr, 119 | std::set>& boot_endpoints) { 120 | uint64_t init_service_type = kad_key_ptr->GetServiceType(); 121 | auto root_routing_ptr = GetRoutingTable(init_service_type, true); 122 | if (!root_routing_ptr) { 123 | root_routing_ptr = GetRoutingTable(kRoot, true); 124 | } 125 | if (!root_routing_ptr) { 126 | TOP_WARN("getrootnodes failed, because kroot not exist"); 127 | return kadmlia::kKadFailed; 128 | } 129 | auto root_routing = std::dynamic_pointer_cast(root_routing_ptr); 130 | if (!root_routing) { 131 | TOP_ERROR("create root manager failed!"); 132 | return kadmlia::kKadFailed; 133 | } 134 | 135 | std::vector nodes; 136 | if (root_routing->GetRootNodes( 137 | kad_key_ptr->Get(), 138 | nodes) != kadmlia::kKadSuccess) { 139 | return kadmlia::kKadFailed; 140 | } 141 | 142 | for (uint32_t i = 0; i < nodes.size(); ++i) { 143 | auto tmp_kad_key = base::GetKadmliaKey(nodes[i]->node_id); 144 | uint64_t node_service_type = tmp_kad_key->GetServiceType(); 145 | if (init_service_type != node_service_type) { 146 | continue; 147 | } 148 | 149 | if (nodes[i]->IsPublicNode()) { 150 | boot_endpoints.insert(std::make_pair(nodes[i]->public_ip, nodes[i]->public_port)); 151 | } 152 | } 153 | return kadmlia::kKadSuccess; 154 | } 155 | 156 | int GetSameNetworkNodes( 157 | base::KadmliaKeyPtr& kad_key_ptr, 158 | std::vector& ret_nodes) { 159 | auto root_routing = std::dynamic_pointer_cast(GetRoutingTable(kRoot, true)); 160 | if (!root_routing) { 161 | TOP_ERROR("create root manager failed!"); 162 | return kadmlia::kKadFailed; 163 | } 164 | 165 | uint64_t init_service_type = kad_key_ptr->GetServiceType(); 166 | // auto local_nodes = root_routing->nodes(); 167 | // for (uint32_t i = 0; i < local_nodes.size(); ++i) { 168 | // auto tmp_kad_key = base::GetKadmliaKey(local_nodes[i]->node_id); 169 | // uint64_t node_service_type = tmp_kad_key->GetServiceType(); 170 | // if (init_service_type != node_service_type) { 171 | // continue; 172 | // } 173 | // ret_nodes.push_back(local_nodes[i]); 174 | // } 175 | // 176 | // if (!ret_nodes.empty()) { 177 | // return kadmlia::kKadSuccess; 178 | // } 179 | 180 | std::vector nodes; 181 | if (root_routing->GetRootNodes( 182 | kad_key_ptr->Get(), 183 | nodes) != kadmlia::kKadSuccess) { 184 | return kadmlia::kKadFailed; 185 | } 186 | 187 | for (uint32_t i = 0; i < nodes.size(); ++i) { 188 | auto tmp_kad_key = base::GetKadmliaKey(nodes[i]->node_id); 189 | uint64_t node_service_type = tmp_kad_key->GetServiceType(); 190 | if (init_service_type != node_service_type) { 191 | continue; 192 | } 193 | ret_nodes.push_back(nodes[i]); 194 | } 195 | return kadmlia::kKadSuccess; 196 | } 197 | 198 | } // namespace wrouter 199 | 200 | } // namespace top 201 | -------------------------------------------------------------------------------- /tests/test_root_routing_manager.cc: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2017-2019 Telos Foundation & contributors 2 | // Distributed under the MIT software license, see the accompanying 3 | // file COPYING or http://www.opensource.org/licenses/mit-license.php. 4 | 5 | #include 6 | 7 | #include 8 | #include 9 | 10 | #include 11 | 12 | #include "xpbase/base/endpoint_util.h" 13 | #include "xpbase/base/kad_key/platform_kadmlia_key.h" 14 | #define protected public 15 | #define private public 16 | #include "xtransport/udp_transport/udp_transport.h" 17 | #include "xkad/routing_table/routing_table.h" 18 | #include "xkad/routing_table/local_node_info.h" 19 | #include "xwrouter/root/root_routing.h" 20 | #include "xwrouter/message_handler/wrouter_message_handler.h" 21 | #include "xtransport/message_manager/multi_message_handler.h" 22 | #include "xwrouter/root/root_routing_manager.h" 23 | #include "xwrouter/register_routing_table.h" 24 | #include "xkad/nat_detect/nat_manager_intf.h" 25 | 26 | namespace top { 27 | 28 | namespace kadmlia { 29 | 30 | namespace test { 31 | 32 | class TestRootRoutingManager : public testing::Test { 33 | public: 34 | static void SetUpTestCase() { 35 | } 36 | 37 | static void TearDownTestCase() { 38 | } 39 | 40 | virtual void SetUp() { 41 | } 42 | 43 | virtual void TearDown() { 44 | } 45 | }; 46 | 47 | TEST_F(TestRootRoutingManager, GetRootNodesFail) { 48 | wrouter::RootRoutingManager root_manager; 49 | std::vector root_nodes; 50 | ASSERT_EQ(root_manager.GetRootNodes(kRoot, root_nodes), kKadFailed); 51 | } 52 | 53 | TEST_F(TestRootRoutingManager, GetRootBootstrapCacheFail) { 54 | wrouter::RootRoutingManager root_manager; 55 | std::set> boot_endpoints; 56 | ASSERT_EQ(root_manager.GetRootBootstrapCache(boot_endpoints), kKadFailed); 57 | } 58 | 59 | TEST_F(TestRootRoutingManager, AddRoutingTableFail) { 60 | wrouter::RootRoutingManager root_manager; 61 | base::Config config; 62 | base::KadmliaKeyPtr kad_key_ptr = std::make_shared(); 63 | ASSERT_EQ(root_manager.AddRoutingTable(nullptr, config, kad_key_ptr), kKadFailed); 64 | 65 | top::transport::UdpTransportPtr udp_transport; 66 | udp_transport.reset(new top::transport::UdpTransport()); 67 | ASSERT_EQ(root_manager.AddRoutingTable(nullptr, config, kad_key_ptr), kKadFailed); 68 | } 69 | 70 | TEST_F(TestRootRoutingManager, ClientTest) { 71 | wrouter::WrouterMessageHandler message_handler; 72 | std::shared_ptr root_manager; 73 | root_manager.reset(new wrouter::RootRoutingManager()); 74 | wrouter::SetRootRoutingManager(root_manager); 75 | base::Config config; 76 | ASSERT_TRUE(config.Init("./conf.ut/test_root.conf")); 77 | std::string local_ip; 78 | ASSERT_TRUE(config.Get("node", "local_ip", local_ip)); 79 | uint16_t local_port = 0; 80 | ASSERT_TRUE(config.Get("node", "local_port", local_port)); 81 | ASSERT_TRUE(config.Set("node", "client_mode", true)); 82 | top::transport::UdpTransportPtr udp_transport; 83 | udp_transport.reset(new top::transport::UdpTransport()); 84 | std::set> public_endpoints_config; 85 | std::string public_endpoints; 86 | if (!config.Get("node", "public_endpoints", public_endpoints)) { 87 | TOP_INFO(" node join must has bootstrap endpoints!"); 88 | return; 89 | } 90 | top::base::ParseEndpoints(public_endpoints, public_endpoints_config); 91 | auto thread_message_handler = std::make_shared(); 92 | thread_message_handler->Init(); 93 | 94 | ASSERT_TRUE(udp_transport->Start(local_ip, local_port, thread_message_handler.get()) == kKadSuccess); 95 | NatManagerIntf::Instance()->SetNatType(kNatTypePublic); 96 | base::KadmliaKeyPtr kad_key_ptr = std::make_shared(); 97 | kad_key_ptr->set_xnetwork_id(kRoot); 98 | ASSERT_EQ(root_manager->AddRoutingTable( 99 | udp_transport, config, kad_key_ptr), kKadSuccess); 100 | std::shared_ptr root_table = root_manager->GetRoutingTable(kRoot); 101 | ASSERT_TRUE(root_table != nullptr); 102 | kad_key_ptr->set_xnetwork_id(kEdgeTopMessage); 103 | ASSERT_EQ(root_manager->AddRoutingTable( 104 | udp_transport, config, kad_key_ptr), kKadSuccess); 105 | std::shared_ptr client_table = root_manager->GetRoutingTable( 106 | kad_key_ptr->GetServiceType()); 107 | ASSERT_TRUE(client_table != nullptr); 108 | std::vector nodes; 109 | ASSERT_EQ(root_manager->GetRootNodes(kRoot, nodes), kKadSuccess); 110 | ASSERT_TRUE(!nodes.empty()); 111 | root_manager->RemoveRoutingTable(kRoot); 112 | root_manager->RemoveRoutingTable(kad_key_ptr->GetServiceType()); 113 | ASSERT_TRUE(root_manager->root_routing_map_.empty()); 114 | udp_transport->Stop(); 115 | } 116 | 117 | TEST_F(TestRootRoutingManager, NodeTest) { 118 | wrouter::WrouterMessageHandler message_handler; 119 | std::shared_ptr root_manager; 120 | root_manager.reset(new wrouter::RootRoutingManager()); 121 | SetRootRoutingManager(root_manager); 122 | base::Config config; 123 | ASSERT_TRUE(config.Init("./conf.ut/test_root.conf")); 124 | std::string local_ip; 125 | ASSERT_TRUE(config.Get("node", "local_ip", local_ip)); 126 | uint16_t local_port = 0; 127 | ASSERT_TRUE(config.Get("node", "local_port", local_port)); 128 | ASSERT_TRUE(config.Set("node", "client_mode", false)); 129 | top::transport::UdpTransportPtr udp_transport; 130 | udp_transport.reset(new top::transport::UdpTransport()); 131 | std::set> public_endpoints_config; 132 | std::string public_endpoints; 133 | if (!config.Get("node", "public_endpoints", public_endpoints)) { 134 | TOP_INFO(" node join must has bootstrap endpoints!"); 135 | return; 136 | } 137 | top::base::ParseEndpoints(public_endpoints, public_endpoints_config); 138 | auto thread_message_handler = std::make_shared(); 139 | thread_message_handler->Init(); 140 | ASSERT_TRUE(udp_transport->Start(local_ip, local_port, thread_message_handler.get()) == kKadSuccess); 141 | NatManagerIntf::Instance()->SetNatType(kNatTypePublic); 142 | base::KadmliaKeyPtr kad_key_ptr = std::make_shared(); 143 | kad_key_ptr->set_xnetwork_id(kRoot); 144 | ASSERT_EQ(root_manager->AddRoutingTable( 145 | udp_transport, config, kad_key_ptr), kKadSuccess); 146 | std::shared_ptr root_table = root_manager->GetRoutingTable(kRoot); 147 | ASSERT_TRUE(root_table != nullptr); 148 | 149 | std::vector nodes; 150 | int ret = root_manager->GetRootNodes(kRoot, nodes); 151 | if (ret != kKadSuccess) { 152 | SleepUs(10 * 1000 * 1000); 153 | ASSERT_EQ(root_manager->GetRootNodes(kRoot, nodes), kKadSuccess); 154 | ASSERT_TRUE(!nodes.empty()); 155 | } else { 156 | ASSERT_TRUE(!nodes.empty()); 157 | } 158 | 159 | std::set> boot_endpoints; 160 | ASSERT_EQ(root_manager->GetBootstrapRootNetwork(kRoot, boot_endpoints), kKadSuccess); 161 | ASSERT_TRUE(!boot_endpoints.empty()); 162 | 163 | kad_key_ptr->set_xnetwork_id(kEdgeTopStorage); 164 | ASSERT_EQ(root_manager->AddRoutingTable( 165 | udp_transport, config, kad_key_ptr), kKadSuccess); 166 | std::shared_ptr storage_table = root_manager->GetRoutingTable( 167 | kad_key_ptr->GetServiceType()); 168 | ASSERT_TRUE(storage_table != nullptr); 169 | kad_key_ptr->set_xnetwork_id(kEdgeTopMessage); 170 | ASSERT_EQ(root_manager->AddRoutingTable( 171 | udp_transport, config, kad_key_ptr), kKadSuccess); 172 | std::shared_ptr message_table = root_manager->GetRoutingTable( 173 | kad_key_ptr->GetServiceType()); 174 | ASSERT_TRUE(message_table != nullptr); 175 | kad_key_ptr->set_xnetwork_id(kEdgeXVPN); 176 | ASSERT_EQ(root_manager->AddRoutingTable( 177 | udp_transport, config, kad_key_ptr), kKadSuccess); 178 | std::shared_ptr vpn_table = root_manager->GetRoutingTable( 179 | kad_key_ptr->GetServiceType()); 180 | ASSERT_TRUE(vpn_table != nullptr); 181 | 182 | root_manager->RemoveRoutingTable(kRoot); 183 | root_manager->RemoveRoutingTable(kEdgeTopMessage); 184 | root_manager->RemoveRoutingTable(kEdgeXVPN); 185 | ASSERT_FALSE(root_manager->root_routing_map_.empty()); 186 | udp_transport->Stop(); 187 | } 188 | 189 | } // namespace test 190 | 191 | } // namespace kadmlia 192 | 193 | } // namespace top 194 | -------------------------------------------------------------------------------- /src/xwrouter.cc: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2017-2019 Telos Foundation & contributors 2 | // Distributed under the MIT software license, see the accompanying 3 | // file COPYING or http://www.opensource.org/licenses/mit-license.php. 4 | 5 | #include "xwrouter/xwrouter.h" 6 | 7 | #include 8 | 9 | #include "xpbase/base/kad_key/get_kadmlia_key.h" 10 | #include "xpbase/base/xip_parser.h" 11 | #include "xpbase/base/kad_key/platform_kadmlia_key.h" 12 | #include "xkad/routing_table/routing_table.h" 13 | #include "xkad/routing_table/routing_utils.h" 14 | #include "xwrouter/register_routing_table.h" 15 | #include "xwrouter/message_handler/wrouter_message_handler.h" 16 | #include "xpbase/base/xip_parser.h" 17 | #include "xkad/routing_table/client_node_manager.h" 18 | #include "xkad/routing_table/dynamic_xip_manager.h" 19 | #include "xtransport/utils/transport_utils.h" 20 | #include "xpbase/base/kad_key/get_kadmlia_key.h" 21 | #include "xpbase/base/uint64_bloomfilter.h" 22 | #include "xpbase/base/redis_client.h" 23 | #include "xkad/gossip/rumor_filter.h" 24 | #include "xgossip/include/broadcast_layered.h" 25 | #include "xgossip/include/gossip_bloomfilter.h" 26 | #include "xgossip/include/gossip_bloomfilter_layer.h" 27 | #include "xgossip/include/gossip_set_layer.h" 28 | #include "xgossip/include/gossip_utils.h" 29 | #include "xbase/xutl.h" 30 | #include "xtransport/message_manager/message_manager_intf.h" 31 | #include "xwrouter/message_handler/xwrouter_xid_handler.h" 32 | #include "xwrouter/message_handler/xwrouter_xip_handler.h" 33 | #include "xgossip/include/gossip_filter.h" 34 | 35 | namespace top { 36 | 37 | using namespace kadmlia; 38 | using namespace gossip; 39 | 40 | namespace wrouter { 41 | 42 | Wrouter::Wrouter() 43 | : max_broadcast_num_(0), 44 | wxid_handler_(nullptr), 45 | wxip_handler_(nullptr) {} 46 | 47 | Wrouter::~Wrouter() { 48 | max_broadcast_num_ = 0; 49 | } 50 | 51 | Wrouter* Wrouter::Instance() { 52 | static Wrouter ins; 53 | return &ins; 54 | } 55 | 56 | void Wrouter::Init( 57 | base::xcontext_t& context, 58 | const uint32_t thread_id, 59 | transport::TransportPtr transport_ptr, 60 | const uint32_t max_broadcast_num) { 61 | assert(transport_ptr); 62 | auto bloom_gossip_ptr = std::make_shared(transport_ptr); 63 | auto layered_gossip_ptr = std::make_shared(transport_ptr); 64 | auto bloom_layer_gossip_ptr = std::make_shared(transport_ptr); 65 | auto set_layer_gossip_ptr = std::make_shared(transport_ptr); 66 | max_broadcast_num_ = max_broadcast_num; 67 | 68 | wxid_handler_ = std::make_shared( 69 | transport_ptr, 70 | bloom_gossip_ptr, 71 | layered_gossip_ptr, 72 | bloom_layer_gossip_ptr, 73 | set_layer_gossip_ptr); 74 | wxip_handler_ = std::make_shared( 75 | transport_ptr, 76 | bloom_gossip_ptr, 77 | layered_gossip_ptr, 78 | bloom_layer_gossip_ptr, 79 | set_layer_gossip_ptr); 80 | 81 | // GossipFilter for global 82 | gossip::GossipFilter::Instance()->Init(); 83 | } 84 | 85 | void Wrouter::register_on_receive_own_callback(on_receive_own_callback_t callback) { 86 | std::unique_lock lock(callback_mutex_); 87 | assert(callback_ == nullptr); 88 | callback_ = callback; 89 | } 90 | 91 | void Wrouter::unregister_on_receive_own_callback() { 92 | std::unique_lock lock(callback_mutex_); 93 | callback_ = nullptr; 94 | } 95 | 96 | int32_t Wrouter::send(base::xpacket_t& packet) { 97 | Xip2Header* xip2_header = ParserXip2Header(packet); 98 | if (!xip2_header) { 99 | TOP_WARN("xip2_header invalid,send failed"); 100 | return enum_xerror_code_fail; 101 | } 102 | if (xip2_header->to_xaddr_low != 0x0 103 | && xip2_header->to_xaddr_low != 0xFFFFFFFFFFFFFFFFULL 104 | && xip2_header->to_xaddr_high != 0x0 105 | && xip2_header->to_xaddr_high != 0xFFFFFFFFFFFFFFFFULL) { 106 | return wxip_handler_->SendPacket(packet); 107 | } 108 | 109 | std::string content((const char*)packet.get_body().data() + enum_xip2_header_len, 110 | packet.get_body().size() - enum_xip2_header_len); 111 | transport::protobuf::RoutingMessage message; 112 | if (!message.ParseFromString(content)) { 113 | TOP_WARN("Message ParseFromString failed"); 114 | return enum_xerror_code_bad_data; 115 | } 116 | return wxid_handler_->SendPacket(message); 117 | } 118 | 119 | int32_t Wrouter::send(transport::protobuf::RoutingMessage& message) { 120 | return wxid_handler_->SendPacket(message); 121 | } 122 | 123 | int32_t Wrouter::SendToLocal(transport::protobuf::RoutingMessage& message) { 124 | return wxid_handler_->SendToLocal(message); 125 | } 126 | 127 | int32_t Wrouter::SendDirect( 128 | transport::protobuf::RoutingMessage& message, 129 | const std::string& ip, 130 | uint16_t port) { 131 | return wxid_handler_->SendDirect(message, ip, port); 132 | } 133 | 134 | int32_t Wrouter::recv( 135 | transport::protobuf::RoutingMessage& message, 136 | base::xpacket_t& packet) { 137 | // Xip2Header* xip2_header = ParserXip2Header(packet); 138 | // if (!xip2_header) { 139 | // TOP_WARN("ParserXip2Header error, recv failed"); 140 | // return enum_xerror_code_fail; 141 | // } 142 | // 143 | // if (xip2_header->to_xaddr_low != 0x0 144 | // && xip2_header->to_xaddr_low != 0xFFFFFFFFFFFFFFFFULL 145 | // && xip2_header->to_xaddr_high != 0x0 146 | // && xip2_header->to_xaddr_high != 0xFFFFFFFFFFFFFFFFULL) { 147 | // int32_t rcode = wxip_handler_->RecvPacket(packet); 148 | // if (rcode == kRecvOwn) { 149 | // return HandleOwnPacket(packet); 150 | // } 151 | // return rcode; 152 | // } 153 | 154 | if (message.hop_num() >= kHopToLive) { 155 | TOP_WARN("stop send msg because hop to live is max: %d [%s] des[%s] " 156 | "message_type[%d]", 157 | kHopToLive, 158 | HexSubstr(message.src_node_id()).c_str(), 159 | HexSubstr(message.des_node_id()).c_str(), 160 | message.type()); 161 | return enum_xerror_code_fail; 162 | } 163 | 164 | int32_t rcode = wxid_handler_->RecvPacket(message, packet); 165 | if (message.type() == kTestChainTrade) { 166 | TOP_WARN("recv2 testchaintradehash:%u", message.gossip().msg_hash()); 167 | } 168 | 169 | if (rcode == kRecvOwn) { 170 | return HandleOwnPacket(message, packet); 171 | } 172 | return rcode; 173 | } 174 | 175 | void Wrouter::SupportRandomPattern() { 176 | WrouterXidHandler* sub_wxid = dynamic_cast(wxid_handler_.get()); 177 | if (sub_wxid != nullptr) { 178 | sub_wxid->SupportRandomPattern(); 179 | } 180 | } 181 | 182 | 183 | bool Wrouter::BroadcastByMultiRandomKadKey( 184 | const transport::protobuf::RoutingMessage& message, 185 | kadmlia::ResponseFunctor call_back, 186 | int64_t recursive_count) { 187 | WrouterXidHandler* sub_wxid = dynamic_cast(wxid_handler_.get()); 188 | if (sub_wxid != nullptr) { 189 | return sub_wxid->BroadcastByMultiRandomKadKey(message, call_back, recursive_count); 190 | } 191 | return false; 192 | } 193 | 194 | int32_t Wrouter::HandleOwnPacket( 195 | transport::protobuf::RoutingMessage& message, 196 | base::xpacket_t& packet) { 197 | if (callback_) { 198 | callback_(message, packet); 199 | } 200 | 201 | WrouterMessageHandler::Instance()->HandleMessage(message, packet); 202 | return enum_xcode_successful; 203 | } 204 | 205 | int32_t Wrouter::HandleOwnSyncPacket( 206 | transport::protobuf::RoutingMessage& message, 207 | base::xpacket_t& packet) { 208 | if (gossip::GossipFilter::Instance()->FilterMessage(message)) { 209 | TOP_NETWORK_DEBUG_FOR_PROTOMESSAGE("wrouter sync filtered", message); 210 | return enum_xcode_successful; 211 | } 212 | 213 | WrouterMessageHandler::Instance()->HandleSyncMessage(message, packet); 214 | return enum_xcode_successful; 215 | } 216 | 217 | int32_t Wrouter::HandleOwnPacket(base::xpacket_t& packet) { 218 | transport::protobuf::RoutingMessage message; 219 | std::string content( 220 | (const char*)packet.get_body().data() + enum_xip2_header_len, 221 | packet.get_body().size() - enum_xip2_header_len); 222 | if (!message.ParseFromString(content)) { 223 | TOP_ERROR("Message ParseFromString from string failed!"); 224 | return enum_xerror_code_fail; 225 | } 226 | return HandleOwnPacket(message, packet); 227 | } 228 | 229 | // parse xip2_header from packet 230 | Xip2Header* Wrouter::ParserXip2Header(base::xpacket_t& packet) 231 | { 232 | if((size_t)packet.get_size() < enum_xip2_header_len)//test size of header and body together 233 | { 234 | TOP_WARN("xip2_header_len invalid, packet_size(%d) smaller than enum_xip2_header_len(%d)", 235 | packet.get_body().size(), 236 | enum_xip2_header_len); 237 | return nullptr; 238 | } 239 | if(packet.get_header().size() > 0) 240 | return (Xip2Header*)(packet.get_header().data()); 241 | else 242 | return (Xip2Header*)(packet.get_body().data()); 243 | } 244 | 245 | 246 | std::vector Wrouter::GetAllLocalIds() { 247 | std::vector all_id_vec; 248 | std::vector vec_type; 249 | GetAllRegisterType(vec_type); 250 | kadmlia::RoutingTablePtr routing_table = GetRoutingTable(kRoot, true); 251 | 252 | if (vec_type.empty() && !routing_table) { 253 | return {}; 254 | } 255 | 256 | all_id_vec.push_back(routing_table->get_local_node_info()->id()); 257 | 258 | for (auto& t : vec_type) { 259 | routing_table = GetRoutingTable(t, false); 260 | if (routing_table) { 261 | all_id_vec.push_back(routing_table->get_local_node_info()->id()); 262 | } 263 | 264 | routing_table = GetRoutingTable(t, true); 265 | if (routing_table) { 266 | all_id_vec.push_back(routing_table->get_local_node_info()->id()); 267 | } 268 | } 269 | return all_id_vec; 270 | } 271 | 272 | std::vector Wrouter::GetAllLocalXips() { 273 | std::vector all_id_vec; 274 | std::vector vec_type; 275 | GetAllRegisterType(vec_type); 276 | kadmlia::RoutingTablePtr routing_table = GetRoutingTable(kRoot, true); 277 | 278 | if (vec_type.empty() && !routing_table) { 279 | return {}; 280 | } 281 | 282 | all_id_vec.push_back(routing_table->get_local_node_info()->xip()); 283 | 284 | for (auto& t : vec_type) { 285 | routing_table = GetRoutingTable(t, false); 286 | if (routing_table) { 287 | all_id_vec.push_back(routing_table->get_local_node_info()->xip()); 288 | } 289 | 290 | routing_table = GetRoutingTable(t, true); 291 | if (routing_table) { 292 | all_id_vec.push_back(routing_table->get_local_node_info()->xip()); 293 | } 294 | } 295 | return all_id_vec; 296 | } 297 | 298 | } // namespace wrouter 299 | 300 | } // namespace top 301 | -------------------------------------------------------------------------------- /src/root_routing_manager.cc: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2017-2019 Telos Foundation & contributors 2 | // Distributed under the MIT software license, see the accompanying 3 | // file COPYING or http://www.opensource.org/licenses/mit-license.php. 4 | 5 | #include "xwrouter/root/root_routing_manager.h" 6 | 7 | #include "xpbase/base/check_cast.h" 8 | #include "xpbase/base/line_parser.h" 9 | #include "xpbase/base/top_log.h" 10 | #include "xpbase/base/endpoint_util.h" 11 | #include "xkad/routing_table/routing_utils.h" 12 | #include "xkad/routing_table/routing_table.h" 13 | #include "xkad/routing_table/local_node_info.h" 14 | #include "xwrouter/register_routing_table.h" 15 | #include "xwrouter/root/root_routing.h" 16 | 17 | namespace top { 18 | 19 | using namespace kadmlia; 20 | 21 | namespace wrouter { 22 | 23 | RootRoutingManager::RootRoutingManager() 24 | : root_routing_map_(), 25 | root_routing_map_mutex_() {} 26 | 27 | RootRoutingManager::~RootRoutingManager() { 28 | std::unique_lock lock(root_routing_map_mutex_); 29 | for (auto iter = root_routing_map_.begin(); iter != root_routing_map_.end(); ++iter) { 30 | iter->second->UnInit(); 31 | } 32 | root_routing_map_.clear(); 33 | } 34 | 35 | int RootRoutingManager::GetRootNodes( 36 | uint32_t network_id, 37 | std::vector& root_nodes) { 38 | RoutingTablePtr routing_table; 39 | { 40 | std::unique_lock lock(root_routing_map_mutex_); 41 | auto iter = root_routing_map_.find(kRoot); 42 | if (iter == root_routing_map_.end()) { 43 | TOP_ERROR("service type[%d] has not added!", network_id); 44 | return kKadFailed; 45 | } 46 | routing_table = iter->second; 47 | } 48 | if (!routing_table) { 49 | TOP_ERROR("get routing table failed!"); 50 | return kKadFailed; 51 | } 52 | RootRouting* root_table = static_cast(routing_table.get()); 53 | if (!routing_table) { 54 | TOP_ERROR("get routing table failed!"); 55 | return kKadFailed; 56 | } 57 | return root_table->GetRootNodes(network_id, root_nodes); 58 | } 59 | 60 | int RootRoutingManager::GetRootNodes( 61 | const std::string& des_id, 62 | std::vector& root_nodes) { 63 | RoutingTablePtr routing_table; 64 | { 65 | std::unique_lock lock(root_routing_map_mutex_); 66 | auto iter = root_routing_map_.find(kRoot); 67 | if (iter == root_routing_map_.end()) { 68 | TOP_ERROR("service type[%s] has not added!", HexEncode(des_id).c_str()); 69 | return kKadFailed; 70 | } 71 | routing_table = iter->second; 72 | } 73 | if (!routing_table) { 74 | TOP_ERROR("get routing table failed!"); 75 | return kKadFailed; 76 | } 77 | RootRouting* root_table = static_cast(routing_table.get()); 78 | return root_table->GetRootNodes(des_id, root_nodes); 79 | } 80 | 81 | int RootRoutingManager::GetRootBootstrapCache( 82 | std::set>& boot_endpoints) { 83 | auto routing_table_ptr = GetRoutingTable(kRoot); 84 | if (!routing_table_ptr) { 85 | TOP_INFO(" no routing_table(kRoot)"); 86 | return kKadFailed; 87 | } 88 | 89 | routing_table_ptr->GetBootstrapCache(boot_endpoints); 90 | return kKadSuccess; 91 | } 92 | 93 | int RootRoutingManager::AddRoutingTable( 94 | std::shared_ptr transport, 95 | const base::Config& config, 96 | base::KadmliaKeyPtr kad_key_ptr, 97 | bool wait_for_joined) { 98 | if (!transport) { 99 | TOP_FATAL("invalid udp transport!"); 100 | return kKadFailed; 101 | } 102 | 103 | if (CreateRoutingTable( 104 | transport, 105 | config, 106 | kad_key_ptr, 107 | wait_for_joined) != kKadSuccess) { 108 | TOP_FATAL("create routing table failed!"); 109 | return kKadFailed; 110 | } 111 | 112 | return kKadSuccess; 113 | } 114 | 115 | void RootRoutingManager::RemoveRoutingTable(uint64_t service_type) { 116 | RoutingTablePtr root_routing = nullptr; 117 | { 118 | std::unique_lock lock(root_routing_map_mutex_); 119 | auto iter = root_routing_map_.find(service_type); 120 | if (iter != root_routing_map_.end()) { 121 | root_routing = iter->second; 122 | root_routing_map_.erase(iter); 123 | } 124 | } 125 | 126 | if (root_routing) { 127 | root_routing->UnInit(); 128 | } 129 | } 130 | 131 | void RootRoutingManager::RemoveAllRoutingTable() { 132 | std::unique_lock lock(root_routing_map_mutex_); 133 | for (auto it = root_routing_map_.begin(); it != root_routing_map_.end();) { 134 | it->second->UnInit(); 135 | it = root_routing_map_.erase(it); 136 | } 137 | } 138 | 139 | 140 | std::shared_ptr RootRoutingManager::GetRoutingTable(uint64_t service_type) { 141 | std::unique_lock lock(root_routing_map_mutex_); 142 | auto iter = root_routing_map_.find(service_type); 143 | if (iter != root_routing_map_.end()) { 144 | return iter->second; 145 | } 146 | return nullptr; 147 | } 148 | 149 | std::shared_ptr RootRoutingManager::GetRoutingTable(const std::string& routing_id) { 150 | std::unique_lock lock(root_routing_map_mutex_); 151 | for (auto& item : root_routing_map_) { 152 | auto routing_ptr = item.second; 153 | if (routing_ptr->get_local_node_info()->id() == routing_id) { 154 | return routing_ptr; 155 | } 156 | } 157 | return nullptr; 158 | } 159 | 160 | int RootRoutingManager::CreateRoutingTable( 161 | std::shared_ptr transport, 162 | const base::Config& config, 163 | base::KadmliaKeyPtr kad_key_ptr, 164 | bool wait_for_joined) { 165 | uint64_t service_type = kRoot; 166 | if (kad_key_ptr->Xip().xnetwork_id() != kRoot) { 167 | service_type = kad_key_ptr->GetServiceType(); 168 | } 169 | { 170 | std::unique_lock lock(root_routing_map_mutex_); 171 | auto iter = root_routing_map_.find(service_type); 172 | if (iter != root_routing_map_.end()) { 173 | TOP_ERROR("service type[%lu] has added!", service_type); 174 | return kKadSuccess; 175 | } 176 | } 177 | 178 | std::set> public_endpoints_config; 179 | GetPublicEndpointsConfig(config, public_endpoints_config); 180 | TOP_INFO("enter CreateRoutingTable:%lu", service_type); 181 | kadmlia::LocalNodeInfoPtr local_node_ptr = kadmlia::CreateLocalInfoFromConfig( 182 | config, 183 | kad_key_ptr); 184 | if (!local_node_ptr) { 185 | TOP_FATAL("create local_node_ptr for service_type(%ld) failed", (long)service_type); 186 | return kKadFailed; 187 | } 188 | RoutingTablePtr routing_table_ptr; 189 | routing_table_ptr.reset(new RootRouting(transport, local_node_ptr)); 190 | 191 | if (!routing_table_ptr->Init()) { 192 | TOP_FATAL("init edge bitvpn routing table failed!"); 193 | return kKadFailed; 194 | } 195 | 196 | routing_table_ptr->get_local_node_info()->set_service_type(service_type); 197 | { 198 | std::unique_lock lock(root_routing_map_mutex_); 199 | root_routing_map_[service_type] = routing_table_ptr; 200 | } 201 | 202 | if (service_type == kRoot) { 203 | bool first_node = false; 204 | if (config.Get("node", "first_node", first_node)) { 205 | if (first_node) { 206 | TOP_INFO("first node started!"); 207 | return kKadSuccess; 208 | } 209 | } 210 | } 211 | 212 | TOP_INFO("before public_endpoints_all"); 213 | std::set> public_endpoints_all; 214 | if (service_type == kRoot) { 215 | routing_table_ptr->GetBootstrapCache(public_endpoints_all); 216 | } else { 217 | GetRootBootstrapCache(public_endpoints_all); 218 | } 219 | 220 | TOP_INFO("before MergeEndpoints"); 221 | base::MergeEndpoints(public_endpoints_config, public_endpoints_all); 222 | if (public_endpoints_all.empty()) { 223 | TOP_FATAL("node join must has bootstrap endpoints!"); 224 | return kKadFailed; 225 | } 226 | 227 | if (wait_for_joined) { 228 | if (routing_table_ptr->MultiJoin(public_endpoints_all) != kKadSuccess) { 229 | TOP_FATAL("MultiJoin failed"); 230 | return kKadFailed; 231 | } 232 | TOP_INFO("MultiJoin success."); 233 | } else { 234 | routing_table_ptr->MultiJoinAsync(public_endpoints_all); 235 | } 236 | 237 | return kKadSuccess; 238 | } 239 | 240 | int RootRoutingManager::GetBootstrapRootNetwork( 241 | uint64_t service_type, 242 | std::set>& boot_endpoints) { 243 | TOP_INFO("get bootstrap from root network, service_type=%llu ...", service_type); 244 | std::vector nodes; 245 | for (int i = 0; i < 3; ++i) { // try 3 times 246 | TOP_INFO("get public nodes, try %d ...", i); 247 | std::vector nodes_tmp; 248 | if (GetRootNodes(service_type, nodes_tmp) != top::kadmlia::kKadSuccess) { 249 | TOP_INFO("get public nodes, try %d failed", i); 250 | continue; 251 | } 252 | 253 | for (auto& node_ptr : nodes_tmp) { 254 | if (node_ptr->IsPublicNode()) { 255 | nodes.push_back(node_ptr); 256 | } else { 257 | TOP_INFO("ignore local node(%s:%d)", 258 | node_ptr->public_ip.c_str(), (int)node_ptr->public_port); 259 | } 260 | } 261 | 262 | // one public node at least 263 | if (nodes.empty()) { 264 | TOP_INFO("get public nodes failed"); 265 | return kKadFailed; 266 | } 267 | } 268 | 269 | boot_endpoints.clear(); 270 | for (auto& node_ptr : nodes) { 271 | boot_endpoints.insert(std::make_pair(node_ptr->public_ip, node_ptr->public_port)); 272 | TOP_INFO("boostrap node(%s:%d)", 273 | node_ptr->public_ip.c_str(), node_ptr->public_port); 274 | } 275 | 276 | return kKadSuccess; 277 | } 278 | 279 | bool RootRoutingManager::GetServiceBootstrapRootNetwork( 280 | uint64_t service_type, 281 | std::set>& boot_endpoints) { 282 | RoutingTablePtr routing_table; 283 | { 284 | std::unique_lock lock(root_routing_map_mutex_); 285 | auto iter = root_routing_map_.find(kRoot); 286 | if (iter == root_routing_map_.end()) { 287 | TOP_ERROR("service type[%d] has not added!", service_type); 288 | return false; 289 | } 290 | routing_table = iter->second; 291 | } 292 | if (!routing_table) { 293 | TOP_ERROR("get routing table failed!"); 294 | return false; 295 | } 296 | RootRouting* root_table = static_cast(routing_table.get()); 297 | return root_table->GetCacheServicePublicNodes(service_type, boot_endpoints); 298 | } 299 | 300 | 301 | bool RootRoutingManager::SetCacheServiceType(uint64_t service_type) { 302 | RoutingTablePtr routing_table; 303 | { 304 | std::unique_lock lock(root_routing_map_mutex_); 305 | auto iter = root_routing_map_.find(kRoot); 306 | if (iter == root_routing_map_.end()) { 307 | TOP_ERROR("service type[%d] has not added!", service_type); 308 | return false; 309 | } 310 | routing_table = iter->second; 311 | } 312 | if (!routing_table) { 313 | TOP_ERROR("get routing table failed!"); 314 | return false; 315 | } 316 | RootRouting* root_table = static_cast(routing_table.get()); 317 | return root_table->SetCacheServiceType(service_type); 318 | } 319 | 320 | } // namespace wrouter 321 | 322 | } // namespace top 323 | -------------------------------------------------------------------------------- /src/multi_routing.cc: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2017-2019 Telos Foundation & contributors 2 | // Distributed under the MIT software license, see the accompanying 3 | // file COPYING or http://www.opensource.org/licenses/mit-license.php. 4 | 5 | #include "xwrouter/multi_routing/multi_routing.h" 6 | 7 | #include 8 | 9 | #include "xpbase/base/top_log.h" 10 | #include "xpbase/base/line_parser.h" 11 | #include "xpbase/base/kad_key/get_kadmlia_key.h" 12 | #include "xpbase/base/kad_key/chain_kadmlia_key.h" 13 | #include "xpbase/base/kad_key/platform_kadmlia_key.h" 14 | #include "xkad/routing_table/local_node_info.h" 15 | #include "xkad/routing_table/routing_table.h" 16 | #include "xwrouter/root/root_routing_manager.h" 17 | #include "xwrouter/multi_routing/small_net_cache.h" 18 | #include "xpbase/base/top_utils.h" 19 | 20 | namespace top { 21 | 22 | using namespace kadmlia; 23 | 24 | namespace wrouter { 25 | 26 | static const int32_t kCheckSingleNodeNetworkPeriod = 3 * 1000 * 1000; 27 | static const uint32_t kCheckSingleNetworkNodesNum = 64; 28 | 29 | MultiRouting::MultiRouting() 30 | : routing_table_map_(), 31 | routing_table_map_mutex_(), 32 | root_manager_ptr_(nullptr) { 33 | timer_.Start( 34 | kCheckSingleNodeNetworkPeriod, 35 | kCheckSingleNodeNetworkPeriod, 36 | std::bind(&MultiRouting::CheckSingleNodeNetwork, this)); 37 | } 38 | 39 | MultiRouting::~MultiRouting() {} 40 | 41 | MultiRouting* MultiRouting::Instance() { 42 | static MultiRouting ins; 43 | return &ins; 44 | } 45 | 46 | void MultiRouting::SetRootRoutingManager(std::shared_ptr root_manager_ptr) { 47 | root_manager_ptr_ = root_manager_ptr; 48 | } 49 | 50 | void MultiRouting::AddRoutingTable(uint64_t type, RoutingTablePtr routing_table) { 51 | std::unique_lock lock(routing_table_map_mutex_); 52 | if(!routing_table) { 53 | return; 54 | } 55 | auto iter = routing_table_map_.find(type); 56 | if (iter != routing_table_map_.end()) { 57 | assert(false); 58 | return; 59 | } 60 | 61 | routing_table_map_[type] = routing_table; 62 | } 63 | 64 | void MultiRouting::RemoveRoutingTable(uint64_t type) { 65 | if (root_manager_ptr_) { 66 | root_manager_ptr_->RemoveRoutingTable(type); 67 | TOP_INFO("remove root routing table: %llu", type); 68 | } 69 | 70 | { 71 | std::unique_lock lock(routing_table_map_mutex_); 72 | auto iter = routing_table_map_.find(type); 73 | if (iter != routing_table_map_.end()) { 74 | iter->second->UnInit(); 75 | routing_table_map_.erase(iter); 76 | TOP_INFO("remove service routing table: %llu", type); 77 | } 78 | } 79 | } 80 | 81 | void MultiRouting::RemoveAllRoutingTable() { 82 | if (root_manager_ptr_) { 83 | root_manager_ptr_->RemoveAllRoutingTable(); 84 | TOP_INFO("remove all root routing table"); 85 | } 86 | 87 | { 88 | std::unique_lock lock(routing_table_map_mutex_); 89 | for (auto it = routing_table_map_.begin(); it != routing_table_map_.end();) { 90 | it->second->UnInit(); 91 | it = routing_table_map_.erase(it); 92 | TOP_INFO("remove all service routing table"); 93 | } 94 | } 95 | } 96 | 97 | RoutingTablePtr MultiRouting::GetRoutingTable(const uint64_t& type, bool root) { 98 | if (root || type == kRoot) { 99 | if (!root_manager_ptr_) { 100 | return nullptr; 101 | } 102 | return root_manager_ptr_->GetRoutingTable(type); 103 | } 104 | return GetServiceRoutingTable(type); 105 | } 106 | 107 | RoutingTablePtr MultiRouting::GetRoutingTable(const std::string& routing_id, bool root) { 108 | if (root) { 109 | if (!root_manager_ptr_) { 110 | return nullptr; 111 | } 112 | return root_manager_ptr_->GetRoutingTable(routing_id); 113 | } 114 | return GetServiceRoutingTable(routing_id); 115 | } 116 | 117 | // base src_service_type and des_service_type, determine which routing table to be choosen 118 | // not considering root routing 119 | RoutingTablePtr MultiRouting::GetSmartRoutingTable(uint64_t type) { 120 | { 121 | std::unique_lock lock(routing_table_map_mutex_); 122 | auto iter = routing_table_map_.find(type); 123 | if (iter != routing_table_map_.end()) { 124 | return iter->second; 125 | } 126 | } 127 | 128 | // TODO(Charlie): may be error 129 | base::KadmliaKeyPtr kad_key = base::GetKadmliaKey(type); 130 | if (kad_key->network_type() == kRoleService) { 131 | type = kad_key->GetServiceType(kRoleEdge); 132 | return GetSmartRoutingTable(type); 133 | } 134 | TOP_ERROR("get smart object failed![%llu]", type); 135 | return nullptr; 136 | } 137 | 138 | uint64_t MultiRouting::TryGetSmartRoutingTable(uint64_t type) { 139 | { 140 | std::unique_lock lock(routing_table_map_mutex_); 141 | auto iter = routing_table_map_.find(type); 142 | if (iter != routing_table_map_.end()) { 143 | return type; 144 | } 145 | } 146 | // not found dest type, then choose the right one routing_table base src_service_type and des_service_type 147 | // usually des_service_type only consider server(not edge) in switch 148 | switch (type) { 149 | case top::kXVPN : { 150 | return kEdgeXVPN; 151 | } 152 | case top::kTopStorage : { 153 | return kEdgeTopStorage; 154 | } 155 | // TODO(smaug) add more kinds of service/server 156 | 157 | default : 158 | break; 159 | } // end switch (des_service_type ... 160 | return kInvalidType; 161 | } 162 | 163 | RoutingTablePtr MultiRouting::GetServiceRoutingTable(const uint64_t& type) { 164 | std::unique_lock lock(routing_table_map_mutex_); 165 | auto iter = routing_table_map_.find(type); 166 | if (iter == routing_table_map_.end()) { 167 | return nullptr; 168 | } 169 | return iter->second; 170 | } 171 | 172 | RoutingTablePtr MultiRouting::GetServiceRoutingTable(const std::string& routing_id) { 173 | std::unique_lock lock(routing_table_map_mutex_); 174 | for (auto& item : routing_table_map_) { 175 | auto routing_ptr = item.second; 176 | if (routing_ptr->get_local_node_info()->id() == routing_id) { 177 | return routing_ptr; 178 | } 179 | } 180 | return nullptr; 181 | } 182 | 183 | void MultiRouting::GetAllRegisterType(std::vector& vec_type) { 184 | vec_type.clear(); 185 | std::unique_lock lock(routing_table_map_mutex_); 186 | for (auto& it : routing_table_map_) { 187 | vec_type.push_back(it.first); 188 | } 189 | } 190 | 191 | bool MultiRouting::CheckTypeExist(uint64_t type) { 192 | std::unique_lock lock(routing_table_map_mutex_); 193 | auto iter = routing_table_map_.find(type); 194 | if (iter != routing_table_map_.end()) { 195 | return true; 196 | } 197 | return false; 198 | } 199 | 200 | bool MultiRouting::SetCacheServiceType(uint64_t service_type) { 201 | if (!root_manager_ptr_) { 202 | TOP_ERROR("MultiRouting:: root_manager_ptr is null"); 203 | return false; 204 | } 205 | return root_manager_ptr_->SetCacheServiceType(service_type); 206 | } 207 | 208 | 209 | bool MultiRouting::GetServiceBootstrapRootNetwork( 210 | uint64_t service_type, 211 | std::set>& boot_endpoints) { 212 | if (!root_manager_ptr_) { 213 | TOP_ERROR("MultiRouting:: root_manager_ptr is null"); 214 | return false; 215 | } 216 | return root_manager_ptr_->GetServiceBootstrapRootNetwork(service_type, boot_endpoints); 217 | } 218 | 219 | // wrapper of Routingtable::SendToClosestNode 220 | // attention: this function will change src_node_id and src_service_type, be careful 221 | void MultiRouting::SendToNetwork(transport::protobuf::RoutingMessage& message, bool add_hop) { 222 | RoutingTablePtr routing_table = GetSmartRoutingTable(message.des_service_type()); 223 | LocalNodeInfoPtr local_node = nullptr; 224 | if (routing_table) { 225 | local_node = routing_table->get_local_node_info(); 226 | if (!local_node) { 227 | TOP_ERROR("SendToNetwork failed, get_local_node_info null"); 228 | return; 229 | } 230 | message.set_src_service_type(local_node->service_type()); 231 | message.set_src_node_id(local_node->id()); 232 | uint32_t des_network_id = GetXNetworkID(message.des_node_id()); 233 | message.set_des_service_type(des_network_id); 234 | TOP_DEBUG("SendToNetwork:: type(%d) local_service_type(%llu)", 235 | message.type(), 236 | local_node->service_type()); 237 | return routing_table->SendToClosestNode(message, add_hop); 238 | } 239 | 240 | // then choose any one 241 | std::unique_lock lock(routing_table_map_mutex_); 242 | auto iter = routing_table_map_.begin(); 243 | routing_table = iter->second; 244 | local_node = routing_table->get_local_node_info(); 245 | if (!local_node) { 246 | TOP_ERROR("SendToNetwork failed, get_local_node_info null"); 247 | return; 248 | } 249 | 250 | message.set_src_service_type(local_node->service_type()); 251 | message.set_src_node_id(local_node->id()); 252 | TOP_DEBUG("SendToNetwork:: type(%d) local_service_type(%llu)", 253 | message.type(), 254 | local_node->service_type()); 255 | return routing_table->SendToClosestNode(message, add_hop); 256 | } 257 | 258 | // this function will not change anything of message, just choose the right routing table, then sendtoclosestnode 259 | void MultiRouting::SendToNetwork(const transport::protobuf::RoutingMessage& message, bool add_hop) { 260 | RoutingTablePtr routing_table = GetSmartRoutingTable(message.des_service_type()); 261 | LocalNodeInfoPtr local_node = nullptr; 262 | if (routing_table) { 263 | TOP_DEBUG("SendToNetwork:: type(%d)", 264 | message.type()); 265 | return routing_table->SendToClosestNode(const_cast(message), 266 | add_hop); 267 | } 268 | 269 | // then choose any one 270 | std::unique_lock lock(routing_table_map_mutex_); 271 | auto iter = routing_table_map_.begin(); 272 | routing_table = iter->second; 273 | local_node = routing_table->get_local_node_info(); 274 | if (!local_node) { 275 | TOP_ERROR("SendToNetwork failed, get_local_node_info null"); 276 | return; 277 | } 278 | 279 | TOP_DEBUG("SendToNetwork:: type(%d)", 280 | message.type()); 281 | return routing_table->SendToClosestNode( 282 | const_cast(message), 283 | add_hop); 284 | } 285 | 286 | void MultiRouting::CheckSingleNodeNetwork() { 287 | std::vector routing_vec; 288 | { 289 | std::unique_lock lock(routing_table_map_mutex_); 290 | for (auto iter = routing_table_map_.begin(); iter != routing_table_map_.end(); ++iter) { 291 | if (iter->second->nodes_size() <= kCheckSingleNetworkNodesNum) { 292 | routing_vec.push_back(iter->second); 293 | } 294 | } 295 | } 296 | 297 | for (auto iter = routing_vec.begin(); iter != routing_vec.end(); ++iter) { 298 | auto service_type = (*iter)->get_local_node_info()->kadmlia_key()->GetServiceType(); 299 | base::KadmliaKeyPtr kad_key = nullptr; 300 | wrouter::NetNode ele_first_node; 301 | //if (SmallNetNodes::Instance()->FindNode(0, ele_first_node, service_type)) { 302 | if (SmallNetNodes::Instance()->FindRandomNode(ele_first_node, service_type)) { 303 | TOP_WARN("findnode small_node_cache account:%s, action CheckSingleNodeNetWork for service_type:%llu", 304 | ele_first_node.m_account.c_str(), 305 | service_type); 306 | auto tmp_service_type = base::CreateServiceType(ele_first_node.m_xip); 307 | if (tmp_service_type == service_type) { 308 | kad_key = base::GetKadmliaKey(ele_first_node.m_xip, ele_first_node.m_account); 309 | } 310 | } 311 | if (!kad_key) { 312 | kad_key = base::GetKadmliaKey(service_type); 313 | } 314 | 315 | std::vector ret_nodes; 316 | int res = GetSameNetworkNodes(kad_key, ret_nodes); 317 | TOP_DEBUG("find neighbors running.[res:%d][size:%d][%d][%d][%d][%d][%d] [%s]", 318 | res, 319 | ret_nodes.size(), 320 | kad_key->xnetwork_id(), 321 | kad_key->zone_id(), 322 | kad_key->cluster_id(), 323 | kad_key->group_id(), 324 | kad_key->xip_type(), 325 | HexEncode(kad_key->Get()).c_str()); 326 | if (res == kadmlia::kKadSuccess) { 327 | if (ret_nodes.empty()) { 328 | continue; 329 | } 330 | 331 | auto node_ptr = ret_nodes[RandomInt32() % ret_nodes.size()]; 332 | (*iter)->FindCloseNodesWithEndpoint( 333 | node_ptr->node_id, 334 | std::make_pair(node_ptr->public_ip, node_ptr->public_port)); 335 | TOP_DEBUG("find neighbors running ok, get same network and join it[%d][%d][%d][%d][%d][%d][%s][ip:%s][port:%d]", 336 | kad_key->xnetwork_id(), 337 | kad_key->zone_id(), 338 | kad_key->cluster_id(), 339 | kad_key->group_id(), 340 | kad_key->xip_type(), 341 | kad_key->network_type(), 342 | HexEncode(node_ptr->node_id).c_str(), 343 | node_ptr->public_ip.c_str(), 344 | node_ptr->public_port); 345 | } 346 | } 347 | } 348 | 349 | } // namespace wrouter 350 | 351 | } // namespace top 352 | -------------------------------------------------------------------------------- /src/xwrouter_xip_handler.cc: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2017-2019 Telos Foundation & contributors 2 | // Distributed under the MIT software license, see the accompanying 3 | // file COPYING or http://www.opensource.org/licenses/mit-license.php. 4 | 5 | #include "xwrouter/message_handler/xwrouter_xip_handler.h" 6 | 7 | #include 8 | 9 | #include "xpbase/base/kad_key/get_kadmlia_key.h" 10 | #include "xpbase/base/xip_parser.h" 11 | #include "xpbase/base/kad_key/platform_kadmlia_key.h" 12 | #include "xkad/routing_table/routing_table.h" 13 | #include "xkad/routing_table/routing_utils.h" 14 | #include "xwrouter/register_routing_table.h" 15 | #include "xwrouter/message_handler/wrouter_message_handler.h" 16 | #include "xpbase/base/xip_parser.h" 17 | #include "xkad/routing_table/client_node_manager.h" 18 | #include "xkad/routing_table/dynamic_xip_manager.h" 19 | #include "xtransport/utils/transport_utils.h" 20 | //#include "xtransport/message_manager/multi_message_handler.h" 21 | #include "xpbase/base/kad_key/get_kadmlia_key.h" 22 | #include "xpbase/base/uint64_bloomfilter.h" 23 | #include "xpbase/base/redis_client.h" 24 | #include "xkad/gossip/rumor_filter.h" 25 | #include "xgossip/include/broadcast_layered.h" 26 | #include "xgossip/include/gossip_bloomfilter.h" 27 | #include "xgossip/include/gossip_bloomfilter_layer.h" 28 | #include "xgossip/include/gossip_utils.h" 29 | #include "xbase/xutl.h" 30 | #include "xtransport/message_manager/message_manager_intf.h" 31 | 32 | namespace top { 33 | 34 | using namespace kadmlia; 35 | using namespace gossip; 36 | 37 | namespace wrouter { 38 | 39 | WrouterXipHandler::WrouterXipHandler( 40 | transport::TransportPtr transport_ptr, 41 | std::shared_ptr bloom_gossip_ptr, 42 | std::shared_ptr layered_gossip_ptr, 43 | std::shared_ptr bloom_layer_gossip_ptr, 44 | std::shared_ptr setlayer_gossip_ptr) 45 | : WrouterHandler( 46 | transport_ptr, 47 | bloom_gossip_ptr, 48 | layered_gossip_ptr, 49 | bloom_layer_gossip_ptr, 50 | setlayer_gossip_ptr) {} 51 | 52 | WrouterXipHandler::~WrouterXipHandler() {} 53 | 54 | int32_t WrouterXipHandler::SendPacket(base::xpacket_t& packet) { 55 | Xip2Header* xip2_header = ParserXip2Header(packet); 56 | if (!xip2_header) { 57 | TOP_WARN("xip2_header invalid, wsend failed"); 58 | return enum_xerror_code_fail; 59 | } 60 | 61 | if (MulticastPacketCheck(xip2_header)) { 62 | return SendMulticast(xip2_header, packet); 63 | } 64 | 65 | if (GossipPacketCheck(xip2_header)) { 66 | return SendGossip(xip2_header, packet); 67 | } 68 | 69 | return SendGeneral(xip2_header, packet); 70 | } 71 | 72 | int32_t WrouterXipHandler::RecvPacket(base::xpacket_t& packet) { 73 | int32_t judgeown_code = JudgeOwnPacket(packet); 74 | 75 | switch (judgeown_code) { 76 | case kJudgeOwnError: { 77 | TOP_WARN("RecvBaseXid failed"); 78 | return kRecvError; 79 | } 80 | case kJudgeOwnYes: { 81 | return kRecvOwn; 82 | } 83 | case kJudgeOwnNoAndContinue: { 84 | SendPacket(packet); 85 | return kRecvOk; 86 | } 87 | case kJudgeOwnYesAndContinue: { 88 | SendPacket(packet); 89 | return kRecvOwn; 90 | } 91 | default: 92 | break; 93 | } 94 | 95 | return kRecvOk; 96 | } 97 | 98 | int32_t WrouterXipHandler::SendDirect( 99 | base::xpacket_t& packet, 100 | const std::string& ip, 101 | uint16_t port) { 102 | packet.set_to_ip_addr(ip); 103 | packet.set_to_ip_port(port); 104 | return transport_ptr_->SendData(packet); 105 | } 106 | 107 | int32_t WrouterXipHandler::SendToLocal(base::xpacket_t& packet) { 108 | return transport_ptr_->SendToLocal(packet); 109 | } 110 | 111 | // parse xip2_header from packet 112 | Xip2Header* WrouterXipHandler::ParserXip2Header(base::xpacket_t& packet) 113 | { 114 | if((size_t)packet.get_size() < enum_xip2_header_len)//test size of header and body together 115 | { 116 | TOP_WARN("xip2_header_len invalid, packet_size(%d) smaller than enum_xip2_header_len(%d)", 117 | packet.get_body().size(), 118 | enum_xip2_header_len); 119 | return nullptr; 120 | } 121 | if(packet.get_header().size() > 0) 122 | return (Xip2Header*)(packet.get_header().data()); 123 | else 124 | return (Xip2Header*)(packet.get_body().data()); 125 | } 126 | 127 | 128 | bool WrouterXipHandler::ParserDesXip(Xip2Header* xip2_header, base::XipParser& des_xip) { 129 | if (!xip2_header) { 130 | TOP_WARN("xip2_header invalid"); 131 | return false; 132 | } 133 | base::XipParser tmp_des_xip(xip2_header->to_xaddr_high, xip2_header->to_xaddr_low); 134 | des_xip = tmp_des_xip; 135 | return des_xip.valid(); 136 | } 137 | 138 | uint64_t WrouterXipHandler::ParserServiceType(uint64_t to_xip_addr_low, uint64_t to_xip_addr_high) { 139 | base::XipParser xip_par(to_xip_addr_high, to_xip_addr_low); 140 | if (!xip_par.valid()) { 141 | return kInvalidType; 142 | } 143 | auto kad_key_ptr = base::GetKadmliaKey(xip_par); 144 | return kad_key_ptr->GetServiceType(); 145 | } 146 | 147 | int32_t WrouterXipHandler::SendGeneral(Xip2Header* xip2_header, base::xpacket_t& packet) { 148 | base::XipParser des_xip; 149 | if (!ParserDesXip(xip2_header, des_xip)) { 150 | TOP_WARN("ParserDesXip failed"); 151 | return enum_xerror_code_bad_packet; 152 | } 153 | 154 | auto kad_key_ptr = base::GetKadmliaKey(des_xip); 155 | uint64_t d_service_type = kad_key_ptr->GetServiceType(); 156 | 157 | // TODO(smaug) there is another way to use root network, getrootnodes first than send 158 | RoutingTablePtr routing_table = FindRoutingTable(false, d_service_type, true); 159 | if (!routing_table) { 160 | TOP_WARN("FindRoutingTable failed"); 161 | return enum_xerror_code_fail; 162 | } 163 | 164 | // choose one src_xip for this packet 165 | if (xip2_header->from_xaddr_low == 0 && xip2_header->from_xaddr_high == 0) { 166 | base::XipParser src_xip = routing_table->get_local_node_info()->GetXipParser(); 167 | uint64_t src_high, src_low; 168 | src_xip.xip(src_high, src_low); 169 | xip2_header->from_xaddr_low = src_low; 170 | xip2_header->from_xaddr_high = src_high; 171 | } 172 | 173 | std::string des_xip_str = des_xip.xip(); 174 | std::vector nodes = GetClosestNodes( 175 | routing_table, 176 | des_xip_str, 177 | //kBroadcastGeneral, 178 | 8, 179 | true); 180 | if (nodes.empty()) { 181 | TOP_WARN("GetClosestNodes failed"); 182 | return enum_xerror_code_fail; 183 | } 184 | // TODO(smaug) 185 | return SendData(packet, nodes, kBroadcastGeneral, false); 186 | } 187 | 188 | int32_t WrouterXipHandler::GossipBroadcast( 189 | const std::string& routing_local_id, 190 | base::xpacket_t& packet, 191 | const std::vector& neighbors, 192 | bool use_filter) { 193 | // TODO(smaug) 194 | return 0; 195 | } 196 | 197 | int32_t WrouterXipHandler::SendData( 198 | base::xpacket_t& packet, 199 | const std::vector& neighbors, 200 | uint32_t next_size, 201 | bool broadcast_stride) { 202 | if (neighbors.empty()) { 203 | TOP_WARN("invliad neighbors"); 204 | return enum_xerror_code_fail; 205 | } 206 | Xip2Header* header_ptr = ParserXip2Header(packet); 207 | if (header_ptr == nullptr) { 208 | TOP_WARN("bad packet header"); 209 | return enum_xerror_code_bad_packet; 210 | } 211 | header_ptr->TTL += 1; 212 | std::vector rest_neighbors; 213 | for (uint32_t i = 0; i < neighbors.size(); ++i) { 214 | NodeInfoPtr node_ptr = neighbors[i]; 215 | if ((node_ptr->xid).empty()) { 216 | TOP_WARN("xid empty"); 217 | continue; 218 | } 219 | 220 | rest_neighbors.push_back(node_ptr); 221 | if (rest_neighbors.size() >= next_size) { 222 | break; 223 | } 224 | } 225 | 226 | base::xpacket_t tmp_packet; 227 | tmp_packet.copy_from(packet); 228 | auto each_call = [this, &packet, &tmp_packet] (kadmlia::NodeInfoPtr node_info_ptr) { 229 | if (!node_info_ptr) { 230 | TOP_WARN("kadmlia::NodeInfoPtr null"); 231 | return false; 232 | } 233 | packet.reset(); 234 | packet.copy_from(tmp_packet); 235 | packet.set_to_ip_addr(node_info_ptr->public_ip); 236 | packet.set_to_ip_port(node_info_ptr->public_port); 237 | if (kadmlia::kKadSuccess != transport_ptr_->SendData(packet)) { 238 | TOP_WARN("SendData to endpoint(%s:%d) failed", 239 | node_info_ptr->public_ip.c_str(), 240 | node_info_ptr->public_port); 241 | return false; 242 | } 243 | return true; 244 | }; 245 | 246 | std::for_each(rest_neighbors.begin(), rest_neighbors.end(), each_call); 247 | return enum_xcode_successful; 248 | } 249 | 250 | int32_t WrouterXipHandler::SendMulticast(Xip2Header* xip2_header, base::xpacket_t& packet){ 251 | base::XipParser des_xip; 252 | if (!ParserDesXip(xip2_header, des_xip)) { 253 | TOP_WARN("ParserDesXip failed"); 254 | return enum_xerror_code_bad_packet; 255 | } 256 | std::string des_xip_str = des_xip.xip(); 257 | 258 | auto kad_key_ptr = base::GetKadmliaKey(des_xip); 259 | uint64_t d_service_type = kad_key_ptr->GetServiceType(); 260 | // multicast same network 261 | if (xip2_header->to_xaddr_low == xip2_header->from_xaddr_low 262 | && xip2_header->to_xaddr_high == xip2_header->from_xaddr_high) { 263 | RoutingTablePtr routing_table = FindRoutingTable(false, d_service_type, false); 264 | if (!routing_table) { 265 | TOP_WARN("FindRoutingTable failed"); 266 | return enum_xerror_code_fail; 267 | } 268 | 269 | std::vector nodes = GetClosestNodes( 270 | routing_table, 271 | des_xip_str, 272 | kBroadcastMax, 273 | true); 274 | if (nodes.empty()) { 275 | TOP_WARN("GetClosestNodes failed"); 276 | return enum_xerror_code_fail; 277 | } 278 | return GossipBroadcast(routing_table->get_local_node_info()->id(), packet, nodes, true); 279 | } 280 | 281 | // multicast to different network 282 | // attention the third parameter, the reason setting true is des is different network,there is need for kRoot 283 | RoutingTablePtr routing_table = FindRoutingTable(false, d_service_type, true); 284 | if (!routing_table) { 285 | TOP_WARN("FindRoutingTable failed"); 286 | return enum_xerror_code_fail; 287 | } 288 | 289 | if (routing_table->get_local_node_info()->GetXipParser().xnetwork_id() == top::kRoot) { 290 | // when packet arrive des network, than,multi_flag = default_value,that is kBroadcastGossip 291 | std::vector nodes = GetClosestNodes( 292 | routing_table, 293 | des_xip_str, 294 | 8, 295 | false); 296 | 297 | if (nodes.empty()) { 298 | TOP_WARN("GetClosestNodes failed"); 299 | return enum_xerror_code_fail; 300 | } 301 | return SendData(packet, nodes, 1, true); 302 | } 303 | 304 | return GossipBroadcast( 305 | routing_table->get_local_node_info()->id(), 306 | packet, 307 | routing_table->nodes(), 308 | true); 309 | } 310 | 311 | 312 | int32_t WrouterXipHandler::SendGossip(Xip2Header* xip2_header, base::xpacket_t& packet) { 313 | auto kad_key_ptr = base::GetKadmliaKey(); 314 | kad_key_ptr->set_xnetwork_id(top::kRoot); 315 | kad_key_ptr->set_network_type(top::kRoleService); 316 | uint64_t d_service_type = kad_key_ptr->GetServiceType(); 317 | RoutingTablePtr routing_table = FindRoutingTable(true, d_service_type, true); 318 | if (!routing_table) { 319 | TOP_WARN("FindRoutingTable failed"); 320 | return enum_xerror_code_fail; 321 | } 322 | 323 | return GossipBroadcast( 324 | routing_table->get_local_node_info()->id(), 325 | packet, 326 | routing_table->nodes(), 327 | true); 328 | } 329 | 330 | int32_t WrouterXipHandler::JudgeOwnPacket(base::xpacket_t& packet) { 331 | Xip2Header* xip2_header = ParserXip2Header(packet); 332 | if (!xip2_header) { 333 | TOP_WARN("xip2_header invalid, JudgeOwnPacket failed"); 334 | return kJudgeOwnError; 335 | } 336 | 337 | if (GossipPacketCheck(xip2_header)) { 338 | // gossip for kRoot, any node will handle this packet 339 | return kJudgeOwnYesAndContinue; 340 | } 341 | 342 | base::XipParser des_xip; 343 | if (!ParserDesXip(xip2_header, des_xip)) { 344 | return kJudgeOwnError; 345 | } 346 | 347 | // broadcast to different network or the same network, exclude kRoot 348 | if (MulticastPacketCheck(xip2_header)) { 349 | return JudgeOwnPacketMulticast(xip2_header, packet); 350 | } 351 | 352 | auto kad_key = GetKadmliaKey(des_xip); 353 | uint64_t d_service_type = kad_key->GetServiceType(); 354 | RoutingTablePtr routing_table = FindRoutingTable(false, d_service_type, false); 355 | if (!routing_table) { 356 | return kJudgeOwnNoAndContinue; 357 | } 358 | 359 | std::string des_xip_str = des_xip.xip(); 360 | std::string match_kad_xip = routing_table->get_local_node_info()->xip(); 361 | 362 | if (match_kad_xip.compare(des_xip_str) == 0 ) { 363 | return kJudgeOwnYes; 364 | } 365 | 366 | // for now, just three cases: 367 | // 1: this is client node , and has more than one kad_xip 368 | // 2: this is node which dispatch dynamic xip for client, so next step will send to client 369 | // 3: this is node which is just not the dest node 370 | 371 | if (routing_table->get_local_node_info()->HasDynamicXip(des_xip_str)) { 372 | // usually this is client 373 | return kJudgeOwnYes; 374 | } 375 | 376 | kadmlia::ClientNodeInfoPtr client_info_ptr = routing_table->get_dy_manager()->FindClientNode(des_xip_str); 377 | if (client_info_ptr) { 378 | packet.set_to_ip_addr(client_info_ptr->public_ip); 379 | packet.set_to_ip_port(client_info_ptr->public_port); 380 | transport_ptr_->SendData(packet); 381 | 382 | return kJudgeOwnNo; 383 | } 384 | 385 | return kJudgeOwnNoAndContinue; 386 | } 387 | 388 | 389 | int32_t WrouterXipHandler::JudgeOwnPacketMulticast(Xip2Header* xip2_header, base::xpacket_t& packet) { 390 | base::XipParser des_xip; 391 | if (!ParserDesXip(xip2_header, des_xip)) { 392 | TOP_WARN("ParserDesXip failed"); 393 | return kJudgeOwnError; 394 | } 395 | std::string des_xip_str = des_xip.xip(); 396 | auto kad_key = base::GetKadmliaKey(des_xip); 397 | uint64_t d_service_type = kad_key->GetServiceType(); 398 | // multicast same network 399 | if (xip2_header->to_xaddr_low == xip2_header->from_xaddr_low 400 | && xip2_header->to_xaddr_high == xip2_header->from_xaddr_high) { 401 | 402 | // attention the third parameter, the reason setting false is at same network, no need for kRoot 403 | RoutingTablePtr routing_table = FindRoutingTable(false, d_service_type, false); 404 | if (!routing_table) { 405 | TOP_WARN("FindRoutingTable failed"); 406 | return kJudgeOwnError; 407 | } 408 | 409 | // find the same network 410 | return kJudgeOwnYesAndContinue; 411 | } 412 | 413 | // multicast to different network 414 | RoutingTablePtr routing_table = FindRoutingTable(false, d_service_type, false); 415 | if (!routing_table) { 416 | TOP_WARN("FindRoutingTable failed"); 417 | return kJudgeOwnNoAndContinue; 418 | } 419 | // find the target network(different from own network) 420 | return kJudgeOwnYesAndContinue; 421 | } 422 | 423 | bool WrouterXipHandler::MulticastPacketCheck(Xip2Header* xip2_header) { 424 | if (xip2_header->flags == enum_xpacket_multicast_flag) { 425 | return true; 426 | } 427 | return false; 428 | } 429 | 430 | // equal broadcast 431 | bool WrouterXipHandler::GossipPacketCheck(Xip2Header* xip2_header) { 432 | if (xip2_header->flags == enum_xpacket_gossip_flag) { 433 | return true; 434 | } 435 | return false; 436 | } 437 | 438 | } // namespace wrouter 439 | 440 | } // namespace top 441 | -------------------------------------------------------------------------------- /xwrouter.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 889F5C1722C5C61E006CD0F3 /* xwrouter_xip_handler.cc in Sources */ = {isa = PBXBuildFile; fileRef = 889F5C1422C5C61E006CD0F3 /* xwrouter_xip_handler.cc */; }; 11 | 889F5C1822C5C61E006CD0F3 /* xwrouter_handler.cc in Sources */ = {isa = PBXBuildFile; fileRef = 889F5C1522C5C61E006CD0F3 /* xwrouter_handler.cc */; }; 12 | 889F5C1922C5C61E006CD0F3 /* xwrouter_xid_handler.cc in Sources */ = {isa = PBXBuildFile; fileRef = 889F5C1622C5C61E006CD0F3 /* xwrouter_xid_handler.cc */; }; 13 | 889F5C1D22C5C634006CD0F3 /* xwrouter_xip_handler.h in Headers */ = {isa = PBXBuildFile; fileRef = 889F5C1A22C5C634006CD0F3 /* xwrouter_xip_handler.h */; }; 14 | 889F5C1E22C5C634006CD0F3 /* xwrouter_handler.h in Headers */ = {isa = PBXBuildFile; fileRef = 889F5C1B22C5C634006CD0F3 /* xwrouter_handler.h */; }; 15 | 889F5C1F22C5C634006CD0F3 /* xwrouter_xid_handler.h in Headers */ = {isa = PBXBuildFile; fileRef = 889F5C1C22C5C634006CD0F3 /* xwrouter_xid_handler.h */; }; 16 | 88D1617122B28E87001838D3 /* wrouter_base_routing.h in Headers */ = {isa = PBXBuildFile; fileRef = 88D1615822B28E87001838D3 /* wrouter_base_routing.h */; }; 17 | 88D1617222B28E87001838D3 /* wrouter_utils.h in Headers */ = {isa = PBXBuildFile; fileRef = 88D1615922B28E87001838D3 /* wrouter_utils.h */; }; 18 | 88D1617322B28E87001838D3 /* rumor_message_handler.h in Headers */ = {isa = PBXBuildFile; fileRef = 88D1615B22B28E87001838D3 /* rumor_message_handler.h */; }; 19 | 88D1617422B28E87001838D3 /* wrouter_message_handler.h in Headers */ = {isa = PBXBuildFile; fileRef = 88D1615C22B28E87001838D3 /* wrouter_message_handler.h */; }; 20 | 88D1617522B28E87001838D3 /* multi_routing.h in Headers */ = {isa = PBXBuildFile; fileRef = 88D1615E22B28E87001838D3 /* multi_routing.h */; }; 21 | 88D1617622B28E87001838D3 /* register_message_handler.h in Headers */ = {isa = PBXBuildFile; fileRef = 88D1615F22B28E87001838D3 /* register_message_handler.h */; }; 22 | 88D1617722B28E87001838D3 /* multi_routing.cc in Sources */ = {isa = PBXBuildFile; fileRef = 88D1616122B28E87001838D3 /* multi_routing.cc */; }; 23 | 88D1617822B28E87001838D3 /* register_message_handler.cc in Sources */ = {isa = PBXBuildFile; fileRef = 88D1616222B28E87001838D3 /* register_message_handler.cc */; }; 24 | 88D1617922B28E87001838D3 /* register_routing_table.cc in Sources */ = {isa = PBXBuildFile; fileRef = 88D1616322B28E87001838D3 /* register_routing_table.cc */; }; 25 | 88D1617A22B28E87001838D3 /* root_message_handler.cc in Sources */ = {isa = PBXBuildFile; fileRef = 88D1616422B28E87001838D3 /* root_message_handler.cc */; }; 26 | 88D1617B22B28E87001838D3 /* root_routing.cc in Sources */ = {isa = PBXBuildFile; fileRef = 88D1616522B28E87001838D3 /* root_routing.cc */; }; 27 | 88D1617C22B28E87001838D3 /* root_routing_manager.cc in Sources */ = {isa = PBXBuildFile; fileRef = 88D1616622B28E87001838D3 /* root_routing_manager.cc */; }; 28 | 88D1617D22B28E87001838D3 /* rumor_message_handler.cc in Sources */ = {isa = PBXBuildFile; fileRef = 88D1616722B28E87001838D3 /* rumor_message_handler.cc */; }; 29 | 88D1617E22B28E87001838D3 /* wrouter_message_handler.cc in Sources */ = {isa = PBXBuildFile; fileRef = 88D1616822B28E87001838D3 /* wrouter_message_handler.cc */; }; 30 | 88D1617F22B28E87001838D3 /* xwrouter.cc in Sources */ = {isa = PBXBuildFile; fileRef = 88D1616922B28E87001838D3 /* xwrouter.cc */; }; 31 | 88D1618022B28E87001838D3 /* root_message_handler.h in Headers */ = {isa = PBXBuildFile; fileRef = 88D1616B22B28E87001838D3 /* root_message_handler.h */; }; 32 | 88D1618122B28E87001838D3 /* root_routing.h in Headers */ = {isa = PBXBuildFile; fileRef = 88D1616C22B28E87001838D3 /* root_routing.h */; }; 33 | 88D1618222B28E87001838D3 /* root_routing_manager.h in Headers */ = {isa = PBXBuildFile; fileRef = 88D1616D22B28E87001838D3 /* root_routing_manager.h */; }; 34 | 88D1618322B28E87001838D3 /* register_routing_table.h in Headers */ = {isa = PBXBuildFile; fileRef = 88D1616E22B28E87001838D3 /* register_routing_table.h */; }; 35 | 88D1618422B28E87001838D3 /* xwrouter.h in Headers */ = {isa = PBXBuildFile; fileRef = 88D1617022B28E87001838D3 /* xwrouter.h */; }; 36 | /* End PBXBuildFile section */ 37 | 38 | /* Begin PBXFileReference section */ 39 | 889F5C1422C5C61E006CD0F3 /* xwrouter_xip_handler.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = xwrouter_xip_handler.cc; sourceTree = ""; }; 40 | 889F5C1522C5C61E006CD0F3 /* xwrouter_handler.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = xwrouter_handler.cc; sourceTree = ""; }; 41 | 889F5C1622C5C61E006CD0F3 /* xwrouter_xid_handler.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = xwrouter_xid_handler.cc; sourceTree = ""; }; 42 | 889F5C1A22C5C634006CD0F3 /* xwrouter_xip_handler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = xwrouter_xip_handler.h; sourceTree = ""; }; 43 | 889F5C1B22C5C634006CD0F3 /* xwrouter_handler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = xwrouter_handler.h; sourceTree = ""; }; 44 | 889F5C1C22C5C634006CD0F3 /* xwrouter_xid_handler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = xwrouter_xid_handler.h; sourceTree = ""; }; 45 | 88D1615822B28E87001838D3 /* wrouter_base_routing.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = wrouter_base_routing.h; sourceTree = ""; }; 46 | 88D1615922B28E87001838D3 /* wrouter_utils.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = wrouter_utils.h; sourceTree = ""; }; 47 | 88D1615B22B28E87001838D3 /* rumor_message_handler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = rumor_message_handler.h; sourceTree = ""; }; 48 | 88D1615C22B28E87001838D3 /* wrouter_message_handler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = wrouter_message_handler.h; sourceTree = ""; }; 49 | 88D1615E22B28E87001838D3 /* multi_routing.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = multi_routing.h; sourceTree = ""; }; 50 | 88D1615F22B28E87001838D3 /* register_message_handler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = register_message_handler.h; sourceTree = SOURCE_ROOT; }; 51 | 88D1616122B28E87001838D3 /* multi_routing.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = multi_routing.cc; sourceTree = ""; }; 52 | 88D1616222B28E87001838D3 /* register_message_handler.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = register_message_handler.cc; sourceTree = ""; }; 53 | 88D1616322B28E87001838D3 /* register_routing_table.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = register_routing_table.cc; sourceTree = ""; }; 54 | 88D1616422B28E87001838D3 /* root_message_handler.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = root_message_handler.cc; sourceTree = ""; }; 55 | 88D1616522B28E87001838D3 /* root_routing.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = root_routing.cc; sourceTree = ""; }; 56 | 88D1616622B28E87001838D3 /* root_routing_manager.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = root_routing_manager.cc; sourceTree = ""; }; 57 | 88D1616722B28E87001838D3 /* rumor_message_handler.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = rumor_message_handler.cc; sourceTree = ""; }; 58 | 88D1616822B28E87001838D3 /* wrouter_message_handler.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = wrouter_message_handler.cc; sourceTree = ""; }; 59 | 88D1616922B28E87001838D3 /* xwrouter.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = xwrouter.cc; sourceTree = ""; }; 60 | 88D1616B22B28E87001838D3 /* root_message_handler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = root_message_handler.h; sourceTree = ""; }; 61 | 88D1616C22B28E87001838D3 /* root_routing.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = root_routing.h; sourceTree = ""; }; 62 | 88D1616D22B28E87001838D3 /* root_routing_manager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = root_routing_manager.h; sourceTree = ""; }; 63 | 88D1616E22B28E87001838D3 /* register_routing_table.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = register_routing_table.h; sourceTree = SOURCE_ROOT; }; 64 | 88D1617022B28E87001838D3 /* xwrouter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = xwrouter.h; sourceTree = SOURCE_ROOT; }; 65 | 99FA78CB22B2726600B5D6BE /* libxwrouter.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libxwrouter.a; sourceTree = BUILT_PRODUCTS_DIR; }; 66 | /* End PBXFileReference section */ 67 | 68 | /* Begin PBXFrameworksBuildPhase section */ 69 | 99FA78C822B2726500B5D6BE /* Frameworks */ = { 70 | isa = PBXFrameworksBuildPhase; 71 | buildActionMask = 2147483647; 72 | files = ( 73 | ); 74 | runOnlyForDeploymentPostprocessing = 0; 75 | }; 76 | /* End PBXFrameworksBuildPhase section */ 77 | 78 | /* Begin PBXGroup section */ 79 | 88D1615622B28E6D001838D3 /* source */ = { 80 | isa = PBXGroup; 81 | children = ( 82 | 88D1615A22B28E87001838D3 /* message_handler */, 83 | 88D1615D22B28E87001838D3 /* multi_routing */, 84 | 88D1615F22B28E87001838D3 /* register_message_handler.h */, 85 | 88D1616E22B28E87001838D3 /* register_routing_table.h */, 86 | 88D1616A22B28E87001838D3 /* root */, 87 | 88D1616F22B28E87001838D3 /* source */, 88 | 88D1616022B28E87001838D3 /* src */, 89 | 88D1615722B28E87001838D3 /* wrouter_utils */, 90 | 88D1617022B28E87001838D3 /* xwrouter.h */, 91 | ); 92 | path = source; 93 | sourceTree = ""; 94 | }; 95 | 88D1615722B28E87001838D3 /* wrouter_utils */ = { 96 | isa = PBXGroup; 97 | children = ( 98 | 88D1615822B28E87001838D3 /* wrouter_base_routing.h */, 99 | 88D1615922B28E87001838D3 /* wrouter_utils.h */, 100 | ); 101 | path = wrouter_utils; 102 | sourceTree = SOURCE_ROOT; 103 | }; 104 | 88D1615A22B28E87001838D3 /* message_handler */ = { 105 | isa = PBXGroup; 106 | children = ( 107 | 88D1615B22B28E87001838D3 /* rumor_message_handler.h */, 108 | 889F5C1B22C5C634006CD0F3 /* xwrouter_handler.h */, 109 | 889F5C1C22C5C634006CD0F3 /* xwrouter_xid_handler.h */, 110 | 889F5C1A22C5C634006CD0F3 /* xwrouter_xip_handler.h */, 111 | 88D1615C22B28E87001838D3 /* wrouter_message_handler.h */, 112 | ); 113 | path = message_handler; 114 | sourceTree = SOURCE_ROOT; 115 | }; 116 | 88D1615D22B28E87001838D3 /* multi_routing */ = { 117 | isa = PBXGroup; 118 | children = ( 119 | 88D1615E22B28E87001838D3 /* multi_routing.h */, 120 | ); 121 | path = multi_routing; 122 | sourceTree = SOURCE_ROOT; 123 | }; 124 | 88D1616022B28E87001838D3 /* src */ = { 125 | isa = PBXGroup; 126 | children = ( 127 | 88D1616122B28E87001838D3 /* multi_routing.cc */, 128 | 889F5C1522C5C61E006CD0F3 /* xwrouter_handler.cc */, 129 | 889F5C1622C5C61E006CD0F3 /* xwrouter_xid_handler.cc */, 130 | 889F5C1422C5C61E006CD0F3 /* xwrouter_xip_handler.cc */, 131 | 88D1616222B28E87001838D3 /* register_message_handler.cc */, 132 | 88D1616322B28E87001838D3 /* register_routing_table.cc */, 133 | 88D1616422B28E87001838D3 /* root_message_handler.cc */, 134 | 88D1616522B28E87001838D3 /* root_routing.cc */, 135 | 88D1616622B28E87001838D3 /* root_routing_manager.cc */, 136 | 88D1616722B28E87001838D3 /* rumor_message_handler.cc */, 137 | 88D1616822B28E87001838D3 /* wrouter_message_handler.cc */, 138 | 88D1616922B28E87001838D3 /* xwrouter.cc */, 139 | ); 140 | path = src; 141 | sourceTree = SOURCE_ROOT; 142 | }; 143 | 88D1616A22B28E87001838D3 /* root */ = { 144 | isa = PBXGroup; 145 | children = ( 146 | 88D1616B22B28E87001838D3 /* root_message_handler.h */, 147 | 88D1616C22B28E87001838D3 /* root_routing.h */, 148 | 88D1616D22B28E87001838D3 /* root_routing_manager.h */, 149 | ); 150 | path = root; 151 | sourceTree = SOURCE_ROOT; 152 | }; 153 | 88D1616F22B28E87001838D3 /* source */ = { 154 | isa = PBXGroup; 155 | children = ( 156 | ); 157 | name = source; 158 | sourceTree = ""; 159 | }; 160 | 99FA78C222B2726500B5D6BE = { 161 | isa = PBXGroup; 162 | children = ( 163 | 88D1615622B28E6D001838D3 /* source */, 164 | 99FA78CC22B2726600B5D6BE /* Products */, 165 | ); 166 | sourceTree = ""; 167 | }; 168 | 99FA78CC22B2726600B5D6BE /* Products */ = { 169 | isa = PBXGroup; 170 | children = ( 171 | 99FA78CB22B2726600B5D6BE /* libxwrouter.a */, 172 | ); 173 | name = Products; 174 | sourceTree = ""; 175 | }; 176 | /* End PBXGroup section */ 177 | 178 | /* Begin PBXHeadersBuildPhase section */ 179 | 99FA78C922B2726500B5D6BE /* Headers */ = { 180 | isa = PBXHeadersBuildPhase; 181 | buildActionMask = 2147483647; 182 | files = ( 183 | 88D1618022B28E87001838D3 /* root_message_handler.h in Headers */, 184 | 889F5C1D22C5C634006CD0F3 /* xwrouter_xip_handler.h in Headers */, 185 | 88D1618322B28E87001838D3 /* register_routing_table.h in Headers */, 186 | 889F5C1F22C5C634006CD0F3 /* xwrouter_xid_handler.h in Headers */, 187 | 88D1617422B28E87001838D3 /* wrouter_message_handler.h in Headers */, 188 | 88D1618422B28E87001838D3 /* xwrouter.h in Headers */, 189 | 88D1618222B28E87001838D3 /* root_routing_manager.h in Headers */, 190 | 88D1617122B28E87001838D3 /* wrouter_base_routing.h in Headers */, 191 | 88D1617622B28E87001838D3 /* register_message_handler.h in Headers */, 192 | 88D1617522B28E87001838D3 /* multi_routing.h in Headers */, 193 | 889F5C1E22C5C634006CD0F3 /* xwrouter_handler.h in Headers */, 194 | 88D1617322B28E87001838D3 /* rumor_message_handler.h in Headers */, 195 | 88D1617222B28E87001838D3 /* wrouter_utils.h in Headers */, 196 | 88D1618122B28E87001838D3 /* root_routing.h in Headers */, 197 | ); 198 | runOnlyForDeploymentPostprocessing = 0; 199 | }; 200 | /* End PBXHeadersBuildPhase section */ 201 | 202 | /* Begin PBXNativeTarget section */ 203 | 99FA78CA22B2726500B5D6BE /* xwrouter */ = { 204 | isa = PBXNativeTarget; 205 | buildConfigurationList = 99FA78CF22B2726600B5D6BE /* Build configuration list for PBXNativeTarget "xwrouter" */; 206 | buildPhases = ( 207 | 99FA78C722B2726500B5D6BE /* Sources */, 208 | 99FA78C822B2726500B5D6BE /* Frameworks */, 209 | 99FA78C922B2726500B5D6BE /* Headers */, 210 | ); 211 | buildRules = ( 212 | ); 213 | dependencies = ( 214 | ); 215 | name = xwrouter; 216 | productName = xwrouter; 217 | productReference = 99FA78CB22B2726600B5D6BE /* libxwrouter.a */; 218 | productType = "com.apple.product-type.library.static"; 219 | }; 220 | /* End PBXNativeTarget section */ 221 | 222 | /* Begin PBXProject section */ 223 | 99FA78C322B2726500B5D6BE /* Project object */ = { 224 | isa = PBXProject; 225 | attributes = { 226 | LastUpgradeCheck = 0830; 227 | ORGANIZATIONNAME = "Taylor Wei"; 228 | TargetAttributes = { 229 | 99FA78CA22B2726500B5D6BE = { 230 | CreatedOnToolsVersion = 8.3.2; 231 | ProvisioningStyle = Automatic; 232 | }; 233 | }; 234 | }; 235 | buildConfigurationList = 99FA78C622B2726500B5D6BE /* Build configuration list for PBXProject "xwrouter" */; 236 | compatibilityVersion = "Xcode 3.2"; 237 | developmentRegion = English; 238 | hasScannedForEncodings = 0; 239 | knownRegions = ( 240 | en, 241 | ); 242 | mainGroup = 99FA78C222B2726500B5D6BE; 243 | productRefGroup = 99FA78CC22B2726600B5D6BE /* Products */; 244 | projectDirPath = ""; 245 | projectRoot = ""; 246 | targets = ( 247 | 99FA78CA22B2726500B5D6BE /* xwrouter */, 248 | ); 249 | }; 250 | /* End PBXProject section */ 251 | 252 | /* Begin PBXSourcesBuildPhase section */ 253 | 99FA78C722B2726500B5D6BE /* Sources */ = { 254 | isa = PBXSourcesBuildPhase; 255 | buildActionMask = 2147483647; 256 | files = ( 257 | 88D1617C22B28E87001838D3 /* root_routing_manager.cc in Sources */, 258 | 88D1617A22B28E87001838D3 /* root_message_handler.cc in Sources */, 259 | 88D1617722B28E87001838D3 /* multi_routing.cc in Sources */, 260 | 88D1617922B28E87001838D3 /* register_routing_table.cc in Sources */, 261 | 889F5C1722C5C61E006CD0F3 /* xwrouter_xip_handler.cc in Sources */, 262 | 88D1617822B28E87001838D3 /* register_message_handler.cc in Sources */, 263 | 889F5C1822C5C61E006CD0F3 /* xwrouter_handler.cc in Sources */, 264 | 88D1617F22B28E87001838D3 /* xwrouter.cc in Sources */, 265 | 889F5C1922C5C61E006CD0F3 /* xwrouter_xid_handler.cc in Sources */, 266 | 88D1617B22B28E87001838D3 /* root_routing.cc in Sources */, 267 | 88D1617D22B28E87001838D3 /* rumor_message_handler.cc in Sources */, 268 | 88D1617E22B28E87001838D3 /* wrouter_message_handler.cc in Sources */, 269 | ); 270 | runOnlyForDeploymentPostprocessing = 0; 271 | }; 272 | /* End PBXSourcesBuildPhase section */ 273 | 274 | /* Begin XCBuildConfiguration section */ 275 | 99FA78CD22B2726600B5D6BE /* Debug */ = { 276 | isa = XCBuildConfiguration; 277 | buildSettings = { 278 | ALWAYS_SEARCH_USER_PATHS = NO; 279 | CLANG_ANALYZER_NONNULL = YES; 280 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 281 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 282 | CLANG_CXX_LIBRARY = "libc++"; 283 | CLANG_ENABLE_MODULES = YES; 284 | CLANG_ENABLE_OBJC_ARC = YES; 285 | CLANG_WARN_BOOL_CONVERSION = YES; 286 | CLANG_WARN_CONSTANT_CONVERSION = YES; 287 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 288 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 289 | CLANG_WARN_EMPTY_BODY = YES; 290 | CLANG_WARN_ENUM_CONVERSION = YES; 291 | CLANG_WARN_INFINITE_RECURSION = YES; 292 | CLANG_WARN_INT_CONVERSION = YES; 293 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 294 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 295 | CLANG_WARN_UNREACHABLE_CODE = YES; 296 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 297 | CODE_SIGN_IDENTITY = "-"; 298 | COPY_PHASE_STRIP = NO; 299 | DEBUG_INFORMATION_FORMAT = dwarf; 300 | ENABLE_STRICT_OBJC_MSGSEND = YES; 301 | ENABLE_TESTABILITY = YES; 302 | GCC_C_LANGUAGE_STANDARD = gnu99; 303 | GCC_DYNAMIC_NO_PIC = NO; 304 | GCC_NO_COMMON_BLOCKS = YES; 305 | GCC_OPTIMIZATION_LEVEL = 0; 306 | GCC_PREPROCESSOR_DEFINITIONS = ( 307 | "DEBUG=1", 308 | "$(inherited)", 309 | ); 310 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 311 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 312 | GCC_WARN_UNDECLARED_SELECTOR = YES; 313 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 314 | GCC_WARN_UNUSED_FUNCTION = YES; 315 | GCC_WARN_UNUSED_VARIABLE = YES; 316 | HEADER_SEARCH_PATHS = ../xdepends/include; 317 | MACOSX_DEPLOYMENT_TARGET = 10.12; 318 | MTL_ENABLE_DEBUG_INFO = YES; 319 | ONLY_ACTIVE_ARCH = YES; 320 | SDKROOT = macosx; 321 | USER_HEADER_SEARCH_PATHS = "../ ../xdepends/include ../third_party"; 322 | }; 323 | name = Debug; 324 | }; 325 | 99FA78CE22B2726600B5D6BE /* Release */ = { 326 | isa = XCBuildConfiguration; 327 | buildSettings = { 328 | ALWAYS_SEARCH_USER_PATHS = NO; 329 | CLANG_ANALYZER_NONNULL = YES; 330 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 331 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 332 | CLANG_CXX_LIBRARY = "libc++"; 333 | CLANG_ENABLE_MODULES = YES; 334 | CLANG_ENABLE_OBJC_ARC = YES; 335 | CLANG_WARN_BOOL_CONVERSION = YES; 336 | CLANG_WARN_CONSTANT_CONVERSION = YES; 337 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 338 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 339 | CLANG_WARN_EMPTY_BODY = YES; 340 | CLANG_WARN_ENUM_CONVERSION = YES; 341 | CLANG_WARN_INFINITE_RECURSION = YES; 342 | CLANG_WARN_INT_CONVERSION = YES; 343 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 344 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 345 | CLANG_WARN_UNREACHABLE_CODE = YES; 346 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 347 | CODE_SIGN_IDENTITY = "-"; 348 | COPY_PHASE_STRIP = NO; 349 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 350 | ENABLE_NS_ASSERTIONS = NO; 351 | ENABLE_STRICT_OBJC_MSGSEND = YES; 352 | GCC_C_LANGUAGE_STANDARD = gnu99; 353 | GCC_NO_COMMON_BLOCKS = YES; 354 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 355 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 356 | GCC_WARN_UNDECLARED_SELECTOR = YES; 357 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 358 | GCC_WARN_UNUSED_FUNCTION = YES; 359 | GCC_WARN_UNUSED_VARIABLE = YES; 360 | HEADER_SEARCH_PATHS = ../xdepends/include; 361 | MACOSX_DEPLOYMENT_TARGET = 10.12; 362 | MTL_ENABLE_DEBUG_INFO = NO; 363 | SDKROOT = macosx; 364 | USER_HEADER_SEARCH_PATHS = "../ ../xdepends/include ../third_party"; 365 | }; 366 | name = Release; 367 | }; 368 | 99FA78D022B2726600B5D6BE /* Debug */ = { 369 | isa = XCBuildConfiguration; 370 | buildSettings = { 371 | EXECUTABLE_PREFIX = lib; 372 | PRODUCT_NAME = "$(TARGET_NAME)"; 373 | }; 374 | name = Debug; 375 | }; 376 | 99FA78D122B2726600B5D6BE /* Release */ = { 377 | isa = XCBuildConfiguration; 378 | buildSettings = { 379 | EXECUTABLE_PREFIX = lib; 380 | PRODUCT_NAME = "$(TARGET_NAME)"; 381 | }; 382 | name = Release; 383 | }; 384 | /* End XCBuildConfiguration section */ 385 | 386 | /* Begin XCConfigurationList section */ 387 | 99FA78C622B2726500B5D6BE /* Build configuration list for PBXProject "xwrouter" */ = { 388 | isa = XCConfigurationList; 389 | buildConfigurations = ( 390 | 99FA78CD22B2726600B5D6BE /* Debug */, 391 | 99FA78CE22B2726600B5D6BE /* Release */, 392 | ); 393 | defaultConfigurationIsVisible = 0; 394 | defaultConfigurationName = Release; 395 | }; 396 | 99FA78CF22B2726600B5D6BE /* Build configuration list for PBXNativeTarget "xwrouter" */ = { 397 | isa = XCConfigurationList; 398 | buildConfigurations = ( 399 | 99FA78D022B2726600B5D6BE /* Debug */, 400 | 99FA78D122B2726600B5D6BE /* Release */, 401 | ); 402 | defaultConfigurationIsVisible = 0; 403 | defaultConfigurationName = Release; 404 | }; 405 | /* End XCConfigurationList section */ 406 | }; 407 | rootObject = 99FA78C322B2726500B5D6BE /* Project object */; 408 | } 409 | -------------------------------------------------------------------------------- /src/root_routing.cc: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2017-2019 Telos Foundation & contributors 2 | // Distributed under the MIT software license, see the accompanying 3 | // file COPYING or http://www.opensource.org/licenses/mit-license.php. 4 | 5 | #include "xwrouter/root/root_routing.h" 6 | 7 | #include "xkad/proto/kadmlia.pb.h" 8 | #include "xkad/routing_table/local_node_info.h" 9 | #include "xkad/routing_table/routing_table.h" 10 | #include "xwrouter/register_routing_table.h" 11 | #include "xkad/routing_table/node_detection_manager.h" 12 | #include "xpbase/base/kad_key/get_kadmlia_key.h" 13 | #include "xpbase/base/sem.h" 14 | #include "xpbase/base/top_string_util.h" 15 | #include "xwrouter/wrouter_utils/wrouter_utils.h" 16 | 17 | namespace top { 18 | 19 | using namespace kadmlia; 20 | 21 | namespace wrouter { 22 | 23 | static const int32_t kGetNodesTimeout = 3; 24 | static const uint32_t kGetNodesSize = 8; 25 | 26 | RootMessageHandler RootRouting::root_message_handler_; 27 | 28 | RootRouting::RootRouting( 29 | std::shared_ptr transport, 30 | kadmlia::LocalNodeInfoPtr local_node_ptr) 31 | : WrouterBaseRouting(transport, kNodeIdSize, local_node_ptr), root_id_set_(), root_id_set_mutex_() {} 32 | 33 | RootRouting::~RootRouting() {} 34 | 35 | bool RootRouting::UnInit() { 36 | if (local_node_ptr_->service_type() != kRoot) { 37 | RoutingTablePtr root_routing_ptr = GetRoutingTable(kRoot, true); 38 | if (root_routing_ptr) { 39 | RootRouting* root = dynamic_cast(root_routing_ptr.get()); 40 | if (root != nullptr) { 41 | root->RemoveNetworkRootId(local_node_ptr_->id()); 42 | } 43 | } 44 | } 45 | return WrouterBaseRouting::UnInit(); 46 | } 47 | 48 | void RootRouting::RemoveNetworkRootId(const std::string& root_id) { 49 | std::unique_lock lock(root_id_set_mutex_); 50 | auto iter = root_id_set_.find(root_id); 51 | if (iter != root_id_set_.end()) { 52 | root_id_set_.erase(iter); 53 | } 54 | } 55 | 56 | void RootRouting::AddNetworkRootId(const std::string& root_id) { 57 | std::unique_lock lock(root_id_set_mutex_); 58 | root_id_set_.insert(root_id); 59 | } 60 | 61 | void RootRouting::SetFreqMessage(transport::protobuf::RoutingMessage& message) { 62 | WrouterBaseRouting::SetFreqMessage(message); 63 | message.set_is_root(true); 64 | } 65 | 66 | bool RootRouting::ContainRootId(const std::string& id) { 67 | if (local_node_ptr_->service_type() == kRoot) { 68 | std::unique_lock lock(root_id_set_mutex_); 69 | auto iter = root_id_set_.find(id); 70 | return iter != root_id_set_.end(); 71 | } 72 | 73 | RoutingTablePtr root_routing_ptr = GetRoutingTable(kRoot, true); 74 | if (!root_routing_ptr) { 75 | TOP_ERROR("root manager must first add root routing!"); 76 | return false; 77 | } 78 | 79 | RootRouting* root = dynamic_cast(root_routing_ptr.get()); 80 | if (!root) { 81 | TOP_ERROR("root manager must first add root routing!"); 82 | return false; 83 | } 84 | return root->ContainRootId(id); 85 | } 86 | 87 | bool RootRouting::NewNodeReplaceOldNode(NodeInfoPtr node, bool remove) { 88 | return WrouterBaseRouting::NewNodeReplaceOldNode(node, remove); 89 | } 90 | 91 | 92 | int RootRouting::AddNode(NodeInfoPtr node) { 93 | int res = WrouterBaseRouting::AddNode(node); 94 | if (res != kKadSuccess) { 95 | return res; 96 | } 97 | 98 | if (node->is_client) { 99 | return res; 100 | } 101 | 102 | return res; 103 | } 104 | 105 | int RootRouting::DropNode(NodeInfoPtr node) { 106 | int res = WrouterBaseRouting::DropNode(node); 107 | if (res != kKadSuccess) { 108 | return res; 109 | } 110 | 111 | if (node->is_client) { 112 | return res; 113 | } 114 | 115 | return res; 116 | } 117 | 118 | 119 | RoutingTablePtr RootRouting::FindRoutingTable(const std::string& msg_des_node_id) { 120 | std::vector vec_type; 121 | GetAllRegisterType(vec_type); 122 | TOP_DEBUG("GetAllRegisterType size %d", vec_type.size()); 123 | auto tmp_routing_table1 = GetRoutingTable(kRoot, true); 124 | auto target_routing_table = tmp_routing_table1; 125 | if (tmp_routing_table1) { 126 | std::string tmp_id1 = tmp_routing_table1->get_local_node_info()->id(); 127 | for (auto& tmp_service_type : vec_type) { 128 | auto tmp_routing_table2 = GetRoutingTable(tmp_service_type, true); 129 | if (!tmp_routing_table2) { 130 | TOP_WARN2("GetRoutingTable %llu empty", tmp_service_type); 131 | continue; 132 | } 133 | std::string tmp_id2 = tmp_routing_table2->get_local_node_info()->id(); 134 | if (!CloserToTarget(tmp_id1, tmp_id2, msg_des_node_id)) { 135 | tmp_id1 = tmp_id2; 136 | tmp_routing_table1 = tmp_routing_table2; 137 | } 138 | } // end for 139 | target_routing_table = tmp_routing_table1; 140 | } 141 | 142 | if (target_routing_table) { 143 | TOP_DEBUG("FindRoutingTable xnetwork_id:%d msg.des_node_id:%s", 144 | target_routing_table->get_local_node_info()->kadmlia_key()->xnetwork_id(), 145 | HexEncode(msg_des_node_id).c_str()); 146 | return target_routing_table; 147 | } 148 | return nullptr; 149 | } 150 | 151 | bool RootRouting::GetRootNodesFromLocalRootRouting( 152 | kadmlia::RoutingTablePtr root_routing, 153 | const std::string& node_id, 154 | std::vector& nodes) { 155 | if (!root_routing) { 156 | return false; 157 | } 158 | base::KadmliaKeyPtr kad_key = base::GetKadmliaKey(node_id); 159 | auto des_routing = root_routing; 160 | auto local_nodes = des_routing->nodes(); 161 | for (uint32_t i = 0; i < local_nodes.size(); ++i) { 162 | if (nodes.size() >= kGetNodesSize) { 163 | break; 164 | } 165 | auto tmp_kad_key = base::GetKadmliaKey(local_nodes[i]->node_id); 166 | uint64_t node_service_type = tmp_kad_key->GetServiceType(); 167 | if (kad_key->GetServiceType() != node_service_type) { 168 | continue; 169 | } 170 | if (local_nodes[i]->public_ip == des_routing->get_local_node_info()->public_ip() && 171 | local_nodes[i]->public_port == des_routing->get_local_node_info()->public_port()) { 172 | continue; 173 | } 174 | nodes.push_back(local_nodes[i]); 175 | } 176 | if (nodes.size() > 0) { 177 | return true; 178 | } 179 | return false; 180 | } 181 | 182 | bool RootRouting::GetRootNodesFromLocal(const std::string& node_id, std::vector& nodes) { 183 | base::KadmliaKeyPtr kad_key = base::GetKadmliaKey(node_id); 184 | auto des_routing = GetRoutingTable(kad_key->GetServiceType(), true); 185 | if (des_routing) { 186 | if (GetRootNodesFromLocalRootRouting(des_routing, node_id, nodes)) { 187 | TOP_DEBUG("getrootnodes found des_routing local, des_node_id(%s)", HexEncode(node_id).c_str()); 188 | return true; 189 | } 190 | return false; 191 | } // end if (des_routing... 192 | 193 | // no des_node_id service_type 194 | std::vector vec_type; 195 | GetAllRegisterType(vec_type); 196 | for (auto& tmp_service_type : vec_type) { 197 | auto tmp_routing_table = GetRoutingTable(tmp_service_type, true); 198 | if (!tmp_routing_table) { 199 | continue; 200 | } 201 | if (GetRootNodesFromLocalRootRouting(tmp_routing_table, node_id, nodes)) { 202 | TOP_DEBUG("getrootnodes found random-des_routing local, des_node_id(%s)", HexEncode(node_id).c_str()); 203 | return true; 204 | } 205 | } // end for 206 | return false; 207 | } 208 | 209 | int RootRouting::GetRootNodes(const std::string& node_id, std::vector& nodes) { 210 | if (GetRootNodesFromLocal(node_id, nodes)) { 211 | // TOP_DEBUG("getrootnodes %d from local, des_node_id(%s)", nodes.size(), HexEncode(node_id).c_str()); 212 | // std::cout << "getrootnodes "<< nodes.size() <<" from local, continue sendto remote" << std::endl; 213 | } 214 | 215 | transport::protobuf::RoutingMessage message; 216 | SetFreqMessage(message); 217 | message.set_des_service_type(kRoot); 218 | message.set_des_node_id(node_id); 219 | message.set_type(kRootMessage); 220 | message.set_id(CallbackManager::MessageId()); 221 | message.set_xid(global_xid->Get()); 222 | #ifndef NDEBUG 223 | auto debug_info = base::StringUtil::str_fmt( 224 | "root routing get nodes, [id: %u] [src: %s], [des: %s] ", 225 | message.id(), 226 | HexEncode(local_node_ptr_->id()).c_str(), 227 | HexEncode(node_id).c_str()); 228 | message.set_debug(debug_info); 229 | TOP_NETWORK_DEBUG_FOR_PROTOMESSAGE("root_get_nodes_begin", message); 230 | #endif 231 | if (local_node_ptr_->client_mode()) { 232 | message.set_client_id(local_node_ptr_->id()); 233 | message.set_relay_flag(false); 234 | } 235 | 236 | /* 237 | std::set root_id_set; 238 | { 239 | std::unique_lock lock(root_id_set_mutex_); 240 | root_id_set = root_id_set_; 241 | } 242 | 243 | for (auto iter = root_id_set.begin(); iter != root_id_set.end(); ++iter) { 244 | transport::protobuf::HopInfo* hop_info = message.add_hop_nodes(); 245 | hop_info->set_node_id(*iter); 246 | } 247 | */ 248 | protobuf::RootGetNodesRequest get_nodes_req; 249 | get_nodes_req.set_id(node_id); 250 | get_nodes_req.set_count(kGetNodesSize); 251 | std::string data; 252 | if (!get_nodes_req.SerializeToString(&data)) { 253 | TOP_WARN("GetNearestNodesRequest SerializeToString failed!"); 254 | return kKadFailed; 255 | } 256 | 257 | protobuf::RootMessage root_message; 258 | root_message.set_message_type(kGetNodesRequest); 259 | root_message.set_data(data); 260 | std::string root_data; 261 | if (!root_message.SerializeToString(&root_data)) { 262 | TOP_INFO("RootMessage SerializeToString failed!"); 263 | return kKadFailed; 264 | } 265 | message.set_data(root_data); 266 | SendToClosestNode(message, false); 267 | base::Sem sem; 268 | int res = kKadFailed; 269 | auto callback = [&res, &sem, &nodes]( 270 | int status, transport::protobuf::RoutingMessage& message, base::xpacket_t& packet) { 271 | if (status == kKadSuccess) { 272 | do { 273 | if (!message.has_data() || message.data().empty()) { 274 | TOP_ERROR("message has no data!"); 275 | break; 276 | } 277 | protobuf::RootMessage get_nodes_res; 278 | if (!get_nodes_res.ParseFromString(message.data())) { 279 | TOP_ERROR("message ParseFromString failed!"); 280 | break; 281 | } 282 | if (!get_nodes_res.has_data() && get_nodes_res.data().empty()) { 283 | TOP_ERROR("message root message has no data!"); 284 | break; 285 | } 286 | protobuf::RootGetNodesResponse nodes_res; 287 | if (!nodes_res.ParseFromString(get_nodes_res.data())) { 288 | TOP_ERROR("message root message ParseFromString!"); 289 | break; 290 | } 291 | for (int i = 0; i < nodes_res.nodes_size(); ++i) { 292 | NodeInfoPtr node_ptr; 293 | node_ptr.reset(new NodeInfo(nodes_res.nodes(i).id())); 294 | node_ptr->public_ip = nodes_res.nodes(i).public_ip(); 295 | node_ptr->public_port = nodes_res.nodes(i).public_port(); 296 | node_ptr->local_ip = nodes_res.nodes(i).local_ip(); 297 | node_ptr->local_port = nodes_res.nodes(i).local_port(); 298 | nodes.push_back(node_ptr); 299 | } 300 | res = kKadSuccess; 301 | } while (0); 302 | } 303 | sem.Post(); 304 | }; 305 | CallbackManager::Instance()->Add(message.id(), kGetNodesTimeout, callback, 1); 306 | sem.Pend(); 307 | return res; 308 | } 309 | 310 | int RootRouting::GetRootNodes(uint64_t service_type, std::vector& nodes) { 311 | std::vector exclude; 312 | base::KadmliaKeyPtr kad_key = base::GetKadmliaKey(service_type); 313 | return GetRootNodes(kad_key->Get(), nodes); 314 | } 315 | 316 | bool RootRouting::Init() { 317 | if (!WrouterBaseRouting::Init()) { 318 | TOP_ERROR("WrouterBaseRouting::Init failed"); 319 | return false; 320 | } 321 | //if (network_id == kRoot) { 322 | if (local_node_ptr_->kadmlia_key()->xnetwork_id() == kRoot) { 323 | local_node_ptr_->set_kadmlia_key(global_xid); 324 | if (!StartBootstrapCacheSaver()) { 325 | TOP_ERROR("WrouterBaseRouting::StartBootstrapCacheSaver failed"); 326 | return false; 327 | } 328 | AddNetworkRootId(local_node_ptr_->id()); 329 | } else { 330 | RoutingTablePtr root_routing_ptr = GetRoutingTable(kRoot, true); 331 | if (!root_routing_ptr) { 332 | TOP_ERROR("root manager must first add root routing!"); 333 | return false; 334 | } 335 | 336 | RootRouting* root = dynamic_cast(root_routing_ptr.get()); 337 | if (!root) { 338 | TOP_ERROR("root manager must first add root routing!"); 339 | return false; 340 | } 341 | root->AddNetworkRootId(local_node_ptr_->id()); 342 | 343 | // add by smaug 344 | NodeInfoPtr self_service_root_node; 345 | self_service_root_node.reset(new NodeInfo(local_node_ptr_->id())); 346 | self_service_root_node->local_ip = local_node_ptr_->local_ip(); 347 | self_service_root_node->local_port = local_node_ptr_->local_port(); 348 | self_service_root_node->public_ip = local_node_ptr_->public_ip(); 349 | self_service_root_node->public_port = local_node_ptr_->public_port(); 350 | self_service_root_node->nat_type = local_node_ptr_->nat_type(); 351 | self_service_root_node->xip = local_node_ptr_->xip(); 352 | self_service_root_node->xid = global_xid->Get(); 353 | self_service_root_node->hash64 = base::xhash64_t::digest(self_service_root_node->xid); 354 | root->AddNode(self_service_root_node); 355 | } 356 | local_node_ptr_->set_is_root(true); 357 | TOP_INFO("bitvpn routing table Init success"); 358 | // return SupportRumor(true); 359 | return true; 360 | } 361 | 362 | int RootRouting::Bootstrap( 363 | const std::string& peer_ip, 364 | uint16_t peer_port, 365 | uint64_t des_service_type) { 366 | return WrouterBaseRouting::Bootstrap(peer_ip, peer_port, kRoot); 367 | } 368 | 369 | void RootRouting::HandleRootGetNodesRequest( 370 | transport::protobuf::RoutingMessage& message, 371 | base::xpacket_t& packet) { 372 | TOP_NETWORK_DEBUG_FOR_PROTOMESSAGE("handle request", message); 373 | base::KadmliaKeyPtr kad_key = base::GetKadmliaKey(message.des_node_id()); 374 | uint64_t node_service_type = kad_key->GetServiceType(); 375 | if (message.des_node_id() != local_node_ptr_->id()) { 376 | std::set root_id_set; 377 | { 378 | std::unique_lock lock(root_id_set_mutex_); 379 | root_id_set = root_id_set_; 380 | } 381 | 382 | bool closest = false; 383 | std::set exclude; 384 | exclude.insert(message.src_node_id()); 385 | RoutingTablePtr target_routing = FindRoutingTable(message.des_node_id()); 386 | NodeInfoPtr closest_node(target_routing->GetClosestNode(message.des_node_id(), false, exclude)); 387 | if (closest_node) { 388 | TOP_NETWORK_DEBUG_FOR_PROTOMESSAGE( 389 | std::string("close: ") + HexEncode(closest_node->node_id) + 390 | std::string(":") + HexEncode(message.des_node_id()), message); 391 | closest = CloserToTarget(target_routing->get_local_node_info()->id(), closest_node->node_id, message.des_node_id()); 392 | } else { 393 | closest = false; 394 | } // end if (closest_node) 395 | 396 | if (!closest) { 397 | TOP_NETWORK_DEBUG_FOR_PROTOMESSAGE("sendto close request", message); 398 | RoutingTablePtr target_routing = FindRoutingTable(message.des_node_id()); 399 | if (!target_routing) { 400 | TOP_WARN("FindRoutingTable failed"); 401 | return; 402 | } 403 | return target_routing->SendToClosestNode(message, false); 404 | } 405 | 406 | TOP_INFO("this is the closest node(%s) of msg.des_node_id(%s)", 407 | HexEncode(target_routing->get_local_node_info()->id()).c_str(), 408 | HexEncode(message.des_node_id()).c_str()); 409 | if (target_routing->get_local_node_info()->kadmlia_key()->GetServiceType() != node_service_type) { 410 | TOP_WARN("target routing table service_type:%llu not equal des_service_type:%llu", 411 | target_routing->get_local_node_info()->kadmlia_key()->GetServiceType(), 412 | node_service_type); 413 | return; 414 | } 415 | } 416 | 417 | if (!message.has_data() || message.data().empty()) { 418 | TOP_WARN("HandleGetGroupNodesRequest has no data!"); 419 | return; 420 | } 421 | 422 | protobuf::RootMessage root_message; 423 | if (!root_message.ParseFromString(message.data())) { 424 | TOP_WARN("RootMessage ParseFromString from string failed!"); 425 | return; 426 | } 427 | 428 | protobuf::RootGetNodesRequest get_nodes_req; 429 | if (!get_nodes_req.ParseFromString(root_message.data())) { 430 | TOP_WARN("RootGetNodesRequest ParseFromString failed!"); 431 | return; 432 | } 433 | 434 | std::vector nodes; 435 | RoutingTablePtr routing_table = GetRoutingTable(node_service_type, true); 436 | if (!routing_table) { 437 | TOP_WARN("GetRoutingTable failed for service_type:%llu", node_service_type); 438 | return; 439 | } 440 | nodes = routing_table->GetClosestNodes(get_nodes_req.id(), get_nodes_req.count() - 1); 441 | auto local_node_ptr = routing_table->get_local_node_info(); 442 | if (!local_node_ptr) { 443 | local_node_ptr = local_node_ptr_; 444 | } 445 | if (local_node_ptr->kadmlia_key()->GetServiceType() != node_service_type) { 446 | return; 447 | } 448 | 449 | transport::protobuf::RoutingMessage res_message; 450 | #ifndef NDEBUG 451 | if (message.has_debug()) { 452 | res_message.set_debug(message.debug()); 453 | } 454 | #endif 455 | 456 | SetFreqMessage(res_message); 457 | res_message.set_src_service_type(message.des_service_type()); 458 | res_message.set_des_service_type(message.src_service_type()); 459 | res_message.set_des_node_id(message.src_node_id()); 460 | res_message.set_type(kRootMessage); 461 | res_message.set_id(message.id()); 462 | if (message.has_client_id()) { 463 | res_message.set_client_id(message.client_id()); 464 | res_message.set_relay_flag(message.relay_flag()); 465 | } 466 | protobuf::RootGetNodesResponse get_nodes_res; 467 | if (local_node_ptr) { 468 | protobuf::NodeInfo* node_info = get_nodes_res.add_nodes(); 469 | node_info->set_id(local_node_ptr->id()); 470 | node_info->set_public_ip(local_node_ptr->public_ip()); 471 | node_info->set_public_port(local_node_ptr->public_port()); 472 | node_info->set_local_ip(local_node_ptr->local_ip()); 473 | node_info->set_local_port(local_node_ptr->local_port()); 474 | } 475 | 476 | auto tmp_ready_nodes = 0; 477 | for (uint32_t i = 0; i < nodes.size(); ++i) { 478 | if (static_cast(get_nodes_res.nodes_size()) >= get_nodes_req.count()) { 479 | break; 480 | } 481 | 482 | if (nodes[i]->node_id == message.des_node_id()) { 483 | continue; 484 | } 485 | if (nodes[i]->xid == message.xid()) { 486 | continue; 487 | } 488 | auto tmp_kad_key = base::GetKadmliaKey(nodes[i]->node_id); 489 | if (tmp_kad_key->GetServiceType() != node_service_type) { 490 | continue; 491 | } 492 | protobuf::NodeInfo* node_info = get_nodes_res.add_nodes(); 493 | node_info->set_id(nodes[i]->node_id); 494 | node_info->set_public_ip(nodes[i]->public_ip); 495 | node_info->set_public_port(nodes[i]->public_port); 496 | node_info->set_local_ip(nodes[i]->local_ip); 497 | node_info->set_local_port(nodes[i]->local_port); 498 | ++tmp_ready_nodes; 499 | } 500 | TOP_DEBUG("nodes:%d ready_nodes:%d filtered:%d", nodes.size(), tmp_ready_nodes, nodes.size()-tmp_ready_nodes); 501 | 502 | std::string data; 503 | if (!get_nodes_res.SerializeToString(&data)) { 504 | TOP_WARN("RootGetNodesResponse SerializeToString failed!"); 505 | return; 506 | } 507 | 508 | TOP_NETWORK_DEBUG_FOR_PROTOMESSAGE( 509 | std::string("response: ") + std::to_string(get_nodes_res.nodes_size()), 510 | message); 511 | protobuf::RootMessage root_res_message; 512 | root_res_message.set_message_type(kGetNodesResponse); 513 | root_res_message.set_data(data); 514 | std::string root_data; 515 | if (!root_res_message.SerializeToString(&root_data)) { 516 | TOP_WARN("RootMessage SerializeToString failed!"); 517 | return; 518 | } 519 | 520 | res_message.set_data(root_data); 521 | if (!local_node_ptr_->client_mode() && 522 | !message.has_client_id() && 523 | ContainRootId(res_message.des_node_id())) { 524 | CallbackManager::Instance()->Callback(res_message.id(), res_message, packet); 525 | return; 526 | } 527 | 528 | if (CheckAndSendRelay(res_message) != kKadSuccess) { 529 | RoutingTablePtr target_routing = FindRoutingTable(res_message.des_node_id()); 530 | if (!target_routing) { 531 | TOP_WARN("FindRoutingTable failed"); 532 | return; 533 | } 534 | target_routing->SendToClosestNode(res_message); 535 | return; 536 | } 537 | } 538 | 539 | void RootRouting::HandleRootGetNodesResponse( 540 | transport::protobuf::RoutingMessage& message, 541 | base::xpacket_t& packet) { 542 | if (message.des_node_id() != local_node_ptr_->id()) { 543 | RoutingTablePtr target_routing = FindRoutingTable(message.des_node_id()); 544 | if (!target_routing) { 545 | TOP_WARN("FindRoutingTable failed"); 546 | return; 547 | } 548 | return target_routing->SendToClosestNode(message); 549 | } 550 | 551 | CallbackManager::Instance()->Callback(message.id(), message, packet); 552 | } 553 | 554 | void RootRouting::HandleMessage( 555 | transport::protobuf::RoutingMessage& message, 556 | base::xpacket_t& packet) { 557 | if (message.type() != kRootMessage) { 558 | return; 559 | } 560 | 561 | if (!message.has_data() || message.data().empty()) { 562 | TOP_WARN("connect request in data is empty."); 563 | return; 564 | } 565 | 566 | protobuf::RootMessage root_message; 567 | if (!root_message.ParseFromString(message.data())) { 568 | TOP_WARN("ConnectRequest ParseFromString from string failed!"); 569 | return; 570 | } 571 | 572 | switch (root_message.message_type()) { 573 | case kGetNodesRequest: 574 | return HandleRootGetNodesRequest(message, packet); 575 | case kGetNodesResponse: 576 | return HandleRootGetNodesResponse(message, packet); 577 | default: 578 | TOP_WARN("invalid root message type[%d].", root_message.message_type()); 579 | break; 580 | } 581 | } 582 | 583 | bool RootRouting::StartBootstrapCacheSaver() { 584 | auto get_public_nodes = [this](std::vector& nodes) { 585 | { 586 | std::unique_lock lock(nodes_mutex_); 587 | for (auto& node_ptr : nodes_) { 588 | if (node_ptr->IsPublicNode()) 589 | nodes.push_back(node_ptr); 590 | } 591 | } 592 | 593 | if (!bootstrap_ip_.empty() && bootstrap_port_ >= 0) { 594 | auto node_ptr = std::make_shared(); 595 | node_ptr->public_ip = bootstrap_ip_; 596 | node_ptr->public_port = bootstrap_port_; 597 | nodes.push_back(node_ptr); 598 | } 599 | }; 600 | 601 | auto get_service_public_nodes = [this](uint64_t service_type, std::vector& nodes) { 602 | std::vector tmp_nodes; 603 | base::KadmliaKeyPtr kad_key = base::GetKadmliaKey(service_type); 604 | if (GetRootNodes(kad_key->Get(), tmp_nodes) != kadmlia::kKadSuccess) { 605 | TOP_WARN("IsPublicNode()) { 611 | nodes.push_back(node_ptr); 612 | } 613 | } 614 | return; 615 | }; 616 | 617 | if (!bootstrap_cache_helper_->Start( 618 | local_node_ptr_->kadmlia_key(), 619 | get_public_nodes, 620 | get_service_public_nodes)) { 621 | TOP_ERROR("boostrap_cache_helper start failed"); 622 | return false; 623 | } 624 | 625 | TOP_INFO("bootstrap_cache_helper start success"); 626 | return true; 627 | } 628 | 629 | bool RootRouting::GetCacheServicePublicNodes( 630 | uint64_t service_type, 631 | std::set>& boot_endpoints) { 632 | return bootstrap_cache_helper_->GetCacheServicePublicNodes(service_type, boot_endpoints); 633 | } 634 | 635 | bool RootRouting::SetCacheServiceType(uint64_t service_type) { 636 | return bootstrap_cache_helper_->SetCacheServiceType(service_type); 637 | } 638 | 639 | } // namespace wrouter 640 | 641 | } // namespace top 642 | --------------------------------------------------------------------------------