Address decoding
parent
61e0c967ea
commit
a641070b9d
|
@ -7,7 +7,8 @@
|
|||
"src/cryptonote_core/cryptonote_format_utils.cpp",
|
||||
"src/crypto/tree-hash.c",
|
||||
"src/crypto/hash.c",
|
||||
"src/crypto/keccak.c"
|
||||
"src/crypto/keccak.c",
|
||||
"src/common/base58.cpp"
|
||||
],
|
||||
"include_dirs": [
|
||||
"src",
|
||||
|
|
27
src/main.cc
27
src/main.cc
|
@ -9,6 +9,7 @@
|
|||
#include "cryptonote_protocol/blobdatatype.h"
|
||||
#include "crypto/crypto.h"
|
||||
#include "crypto/hash.h"
|
||||
#include "common/base58.h"
|
||||
|
||||
using namespace node;
|
||||
using namespace v8;
|
||||
|
@ -46,9 +47,31 @@ Handle<Value> convert_blob(const Arguments& args) {
|
|||
return scope.Close(buff->handle_);
|
||||
}
|
||||
|
||||
Handle<Value> address_decode(const Arguments& args) {
|
||||
HandleScope scope;
|
||||
|
||||
if (args.Length() < 1)
|
||||
return except("You must provide one argument.");
|
||||
|
||||
Local<Object> target = args[0]->ToObject();
|
||||
|
||||
if (!Buffer::HasInstance(target))
|
||||
return except("Argument should be a buffer object.");
|
||||
|
||||
blobdata input = std::string(Buffer::Data(target), Buffer::Length(target));
|
||||
blobdata output = "";
|
||||
|
||||
uint64_t prefix;
|
||||
|
||||
tools::base58::decode_addr(input, prefix, output);
|
||||
|
||||
Buffer* buff = Buffer::New(output.data(), output.size());
|
||||
return scope.Close(buff->handle_);
|
||||
}
|
||||
|
||||
void init(Handle<Object> exports) {
|
||||
exports->Set(String::NewSymbol("convert_blob"),
|
||||
FunctionTemplate::New(convert_blob)->GetFunction());
|
||||
exports->Set(String::NewSymbol("convert_blob"), FunctionTemplate::New(convert_blob)->GetFunction());
|
||||
exports->Set(String::NewSymbol("address_decode"), FunctionTemplate::New(address_decode)->GetFunction());
|
||||
}
|
||||
|
||||
NODE_MODULE(cryptonote, init)
|
||||
|
|
|
@ -0,0 +1,204 @@
|
|||
// Copyright (c) 2012-2013 The Cryptonote developers
|
||||
// Distributed under the MIT/X11 software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#pragma once
|
||||
#include <boost/thread.hpp>
|
||||
#include <boost/bind.hpp>
|
||||
#include <boost/foreach.hpp>
|
||||
#include <boost/bimap.hpp>
|
||||
#include <boost/multi_index_container.hpp>
|
||||
#include <boost/multi_index/ordered_index.hpp>
|
||||
#include <boost/multi_index/identity.hpp>
|
||||
#include <boost/multi_index/member.hpp>
|
||||
#include <boost/multi_index/global_fun.hpp>
|
||||
#include <boost/program_options/options_description.hpp>
|
||||
#include <boost/program_options/variables_map.hpp>
|
||||
#include <boost/serialization/version.hpp>
|
||||
|
||||
#include "warnings.h"
|
||||
#include "net/levin_server_cp2.h"
|
||||
#include "p2p_protocol_defs.h"
|
||||
#include "storages/levin_abstract_invoke2.h"
|
||||
#include "net_peerlist.h"
|
||||
#include "p2p_networks.h"
|
||||
#include "math_helper.h"
|
||||
#include "net_node_common.h"
|
||||
|
||||
using namespace epee;
|
||||
|
||||
PUSH_WARNINGS
|
||||
DISABLE_VS_WARNINGS(4355)
|
||||
|
||||
namespace nodetool
|
||||
{
|
||||
template<class base_type>
|
||||
struct p2p_connection_context_t: base_type //t_payload_net_handler::connection_context //public net_utils::connection_context_base
|
||||
{
|
||||
peerid_type peer_id;
|
||||
};
|
||||
|
||||
template<class t_payload_net_handler>
|
||||
class node_server: public levin::levin_commands_handler<p2p_connection_context_t<typename t_payload_net_handler::connection_context> >,
|
||||
public i_p2p_endpoint<typename t_payload_net_handler::connection_context>
|
||||
{
|
||||
struct by_conn_id{};
|
||||
struct by_peer_id{};
|
||||
struct by_addr{};
|
||||
|
||||
typedef p2p_connection_context_t<typename t_payload_net_handler::connection_context> p2p_connection_context;
|
||||
|
||||
typedef COMMAND_HANDSHAKE_T<typename t_payload_net_handler::payload_type> COMMAND_HANDSHAKE;
|
||||
typedef COMMAND_TIMED_SYNC_T<typename t_payload_net_handler::payload_type> COMMAND_TIMED_SYNC;
|
||||
|
||||
public:
|
||||
typedef t_payload_net_handler payload_net_handler;
|
||||
// Some code
|
||||
node_server(t_payload_net_handler& payload_handler):m_payload_handler(payload_handler), m_allow_local_ip(false), m_hide_my_port(false)
|
||||
{}
|
||||
|
||||
static void init_options(boost::program_options::options_description& desc);
|
||||
|
||||
bool run();
|
||||
bool init(const boost::program_options::variables_map& vm);
|
||||
bool deinit();
|
||||
bool send_stop_signal();
|
||||
uint32_t get_this_peer_port(){return m_listenning_port;}
|
||||
t_payload_net_handler& get_payload_object();
|
||||
|
||||
template <class Archive, class t_version_type>
|
||||
void serialize(Archive &a, const t_version_type ver)
|
||||
{
|
||||
a & m_peerlist;
|
||||
a & m_config.m_peer_id;
|
||||
}
|
||||
// debug functions
|
||||
bool log_peerlist();
|
||||
bool log_connections();
|
||||
virtual uint64_t get_connections_count();
|
||||
size_t get_outgoing_connections_count();
|
||||
peerlist_manager& get_peerlist_manager(){return m_peerlist;}
|
||||
private:
|
||||
typedef COMMAND_REQUEST_STAT_INFO_T<typename t_payload_net_handler::stat_info> COMMAND_REQUEST_STAT_INFO;
|
||||
|
||||
CHAIN_LEVIN_INVOKE_MAP2(p2p_connection_context); //move levin_commands_handler interface invoke(...) callbacks into invoke map
|
||||
CHAIN_LEVIN_NOTIFY_MAP2(p2p_connection_context); //move levin_commands_handler interface notify(...) callbacks into nothing
|
||||
|
||||
BEGIN_INVOKE_MAP2(node_server)
|
||||
HANDLE_INVOKE_T2(COMMAND_HANDSHAKE, &node_server::handle_handshake)
|
||||
HANDLE_INVOKE_T2(COMMAND_TIMED_SYNC, &node_server::handle_timed_sync)
|
||||
HANDLE_INVOKE_T2(COMMAND_PING, &node_server::handle_ping)
|
||||
#ifdef ALLOW_DEBUG_COMMANDS
|
||||
HANDLE_INVOKE_T2(COMMAND_REQUEST_STAT_INFO, &node_server::handle_get_stat_info)
|
||||
HANDLE_INVOKE_T2(COMMAND_REQUEST_NETWORK_STATE, &node_server::handle_get_network_state)
|
||||
HANDLE_INVOKE_T2(COMMAND_REQUEST_PEER_ID, &node_server::handle_get_peer_id)
|
||||
#endif
|
||||
CHAIN_INVOKE_MAP_TO_OBJ_FORCE_CONTEXT(m_payload_handler, typename t_payload_net_handler::connection_context&)
|
||||
END_INVOKE_MAP2()
|
||||
|
||||
//----------------- commands handlers ----------------------------------------------
|
||||
int handle_handshake(int command, typename COMMAND_HANDSHAKE::request& arg, typename COMMAND_HANDSHAKE::response& rsp, p2p_connection_context& context);
|
||||
int handle_timed_sync(int command, typename COMMAND_TIMED_SYNC::request& arg, typename COMMAND_TIMED_SYNC::response& rsp, p2p_connection_context& context);
|
||||
int handle_ping(int command, COMMAND_PING::request& arg, COMMAND_PING::response& rsp, p2p_connection_context& context);
|
||||
#ifdef ALLOW_DEBUG_COMMANDS
|
||||
int handle_get_stat_info(int command, typename COMMAND_REQUEST_STAT_INFO::request& arg, typename COMMAND_REQUEST_STAT_INFO::response& rsp, p2p_connection_context& context);
|
||||
int handle_get_network_state(int command, COMMAND_REQUEST_NETWORK_STATE::request& arg, COMMAND_REQUEST_NETWORK_STATE::response& rsp, p2p_connection_context& context);
|
||||
int handle_get_peer_id(int command, COMMAND_REQUEST_PEER_ID::request& arg, COMMAND_REQUEST_PEER_ID::response& rsp, p2p_connection_context& context);
|
||||
#endif
|
||||
bool init_config();
|
||||
bool make_default_config();
|
||||
bool store_config();
|
||||
bool check_trust(const proof_of_trust& tr);
|
||||
|
||||
|
||||
//----------------- levin_commands_handler -------------------------------------------------------------
|
||||
virtual void on_connection_new(p2p_connection_context& context);
|
||||
virtual void on_connection_close(p2p_connection_context& context);
|
||||
virtual void callback(p2p_connection_context& context);
|
||||
//----------------- i_p2p_endpoint -------------------------------------------------------------
|
||||
virtual bool relay_notify_to_all(int command, const std::string& data_buff, const epee::net_utils::connection_context_base& context);
|
||||
virtual bool invoke_command_to_peer(int command, const std::string& req_buff, std::string& resp_buff, const epee::net_utils::connection_context_base& context);
|
||||
virtual bool invoke_notify_to_peer(int command, const std::string& req_buff, const epee::net_utils::connection_context_base& context);
|
||||
virtual bool drop_connection(const epee::net_utils::connection_context_base& context);
|
||||
virtual void request_callback(const epee::net_utils::connection_context_base& context);
|
||||
virtual void for_each_connection(std::function<bool(typename t_payload_net_handler::connection_context&, peerid_type)> f);
|
||||
//-----------------------------------------------------------------------------------------------
|
||||
bool parse_peer_from_string(nodetool::net_address& pe, const std::string& node_addr);
|
||||
bool handle_command_line(const boost::program_options::variables_map& vm);
|
||||
bool idle_worker();
|
||||
bool handle_remote_peerlist(const std::list<peerlist_entry>& peerlist, time_t local_time, const net_utils::connection_context_base& context);
|
||||
bool get_local_node_data(basic_node_data& node_data);
|
||||
//bool get_local_handshake_data(handshake_data& hshd);
|
||||
|
||||
bool merge_peerlist_with_local(const std::list<peerlist_entry>& bs);
|
||||
bool fix_time_delta(std::list<peerlist_entry>& local_peerlist, time_t local_time, int64_t& delta);
|
||||
|
||||
bool connections_maker();
|
||||
bool peer_sync_idle_maker();
|
||||
bool do_handshake_with_peer(peerid_type& pi, p2p_connection_context& context, bool just_take_peerlist = false);
|
||||
bool do_peer_timed_sync(const net_utils::connection_context_base& context, peerid_type peer_id);
|
||||
|
||||
bool make_new_connection_from_peerlist(bool use_white_list);
|
||||
bool try_to_connect_and_handshake_with_new_peer(const net_address& na, bool just_take_peerlist = false, uint64_t last_seen_stamp = 0, bool white = true);
|
||||
size_t get_random_index_with_fixed_probability(size_t max_index);
|
||||
bool is_peer_used(const peerlist_entry& peer);
|
||||
bool is_addr_connected(const net_address& peer);
|
||||
template<class t_callback>
|
||||
bool try_ping(basic_node_data& node_data, p2p_connection_context& context, t_callback cb);
|
||||
bool make_expected_connections_count(bool white_list, size_t expected_connections);
|
||||
|
||||
//debug functions
|
||||
std::string print_connections_container();
|
||||
|
||||
|
||||
typedef net_utils::boosted_tcp_server<levin::async_protocol_handler<p2p_connection_context> > net_server;
|
||||
|
||||
struct config
|
||||
{
|
||||
network_config m_net_config;
|
||||
uint64_t m_peer_id;
|
||||
|
||||
BEGIN_KV_SERIALIZE_MAP()
|
||||
KV_SERIALIZE(m_net_config)
|
||||
KV_SERIALIZE(m_peer_id)
|
||||
END_KV_SERIALIZE_MAP()
|
||||
};
|
||||
|
||||
config m_config;
|
||||
std::string m_config_folder;
|
||||
|
||||
bool m_have_address;
|
||||
bool m_first_connection_maker_call;
|
||||
uint32_t m_listenning_port;
|
||||
uint32_t m_external_port;
|
||||
uint32_t m_ip_address;
|
||||
bool m_allow_local_ip;
|
||||
bool m_hide_my_port;
|
||||
|
||||
//critical_section m_connections_lock;
|
||||
//connections_indexed_container m_connections;
|
||||
|
||||
t_payload_net_handler& m_payload_handler;
|
||||
peerlist_manager m_peerlist;
|
||||
|
||||
math_helper::once_a_time_seconds<P2P_DEFAULT_HANDSHAKE_INTERVAL> m_peer_handshake_idle_maker_interval;
|
||||
math_helper::once_a_time_seconds<1> m_connections_maker_interval;
|
||||
math_helper::once_a_time_seconds<60*30, false> m_peerlist_store_interval;
|
||||
|
||||
std::string m_bind_ip;
|
||||
std::string m_port;
|
||||
#ifdef ALLOW_DEBUG_COMMANDS
|
||||
uint64_t m_last_stat_request_time;
|
||||
#endif
|
||||
std::list<net_address> m_priority_peers;
|
||||
std::vector<net_address> m_seed_nodes;
|
||||
std::list<nodetool::peerlist_entry> m_command_line_peers;
|
||||
uint64_t m_peer_livetime;
|
||||
//keep connections to initiate some interactions
|
||||
net_server m_net_server;
|
||||
};
|
||||
}
|
||||
|
||||
#include "net_node.inl"
|
||||
|
||||
POP_WARNINGS
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,62 @@
|
|||
// Copyright (c) 2012-2013 The Cryptonote developers
|
||||
// Distributed under the MIT/X11 software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <boost/uuid/uuid.hpp>
|
||||
#include "net/net_utils_base.h"
|
||||
#include "p2p_protocol_defs.h"
|
||||
|
||||
namespace nodetool
|
||||
{
|
||||
|
||||
typedef boost::uuids::uuid uuid;
|
||||
typedef boost::uuids::uuid net_connection_id;
|
||||
|
||||
template<class t_connection_context>
|
||||
struct i_p2p_endpoint
|
||||
{
|
||||
virtual bool relay_notify_to_all(int command, const std::string& data_buff, const epee::net_utils::connection_context_base& context)=0;
|
||||
virtual bool invoke_command_to_peer(int command, const std::string& req_buff, std::string& resp_buff, const epee::net_utils::connection_context_base& context)=0;
|
||||
virtual bool invoke_notify_to_peer(int command, const std::string& req_buff, const epee::net_utils::connection_context_base& context)=0;
|
||||
virtual bool drop_connection(const epee::net_utils::connection_context_base& context)=0;
|
||||
virtual void request_callback(const epee::net_utils::connection_context_base& context)=0;
|
||||
virtual uint64_t get_connections_count()=0;
|
||||
virtual void for_each_connection(std::function<bool(t_connection_context&, peerid_type)> f)=0;
|
||||
};
|
||||
|
||||
template<class t_connection_context>
|
||||
struct p2p_endpoint_stub: public i_p2p_endpoint<t_connection_context>
|
||||
{
|
||||
virtual bool relay_notify_to_all(int command, const std::string& data_buff, const epee::net_utils::connection_context_base& context)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
virtual bool invoke_command_to_peer(int command, const std::string& req_buff, std::string& resp_buff, const epee::net_utils::connection_context_base& context)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
virtual bool invoke_notify_to_peer(int command, const std::string& req_buff, const epee::net_utils::connection_context_base& context)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
virtual bool drop_connection(const epee::net_utils::connection_context_base& context)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
virtual void request_callback(const epee::net_utils::connection_context_base& context)
|
||||
{
|
||||
|
||||
}
|
||||
virtual void for_each_connection(std::function<bool(t_connection_context&,peerid_type)> f)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
virtual uint64_t get_connections_count()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
};
|
||||
}
|
|
@ -0,0 +1,371 @@
|
|||
// Copyright (c) 2012-2013 The Cryptonote developers
|
||||
// Distributed under the MIT/X11 software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <list>
|
||||
#include <set>
|
||||
#include <map>
|
||||
#include <boost/foreach.hpp>
|
||||
//#include <boost/bimap.hpp>
|
||||
//#include <boost/bimap/multiset_of.hpp>
|
||||
#include <boost/archive/binary_oarchive.hpp>
|
||||
#include <boost/archive/binary_iarchive.hpp>
|
||||
#include <boost/serialization/version.hpp>
|
||||
|
||||
#include <boost/multi_index_container.hpp>
|
||||
#include <boost/multi_index/ordered_index.hpp>
|
||||
#include <boost/multi_index/identity.hpp>
|
||||
#include <boost/multi_index/member.hpp>
|
||||
|
||||
|
||||
#include "syncobj.h"
|
||||
#include "net/local_ip.h"
|
||||
#include "p2p_protocol_defs.h"
|
||||
#include "cryptonote_config.h"
|
||||
#include "net_peerlist_boost_serialization.h"
|
||||
|
||||
|
||||
|
||||
namespace nodetool
|
||||
{
|
||||
|
||||
|
||||
/************************************************************************/
|
||||
/* */
|
||||
/************************************************************************/
|
||||
class peerlist_manager
|
||||
{
|
||||
public:
|
||||
bool init(bool allow_local_ip);
|
||||
bool deinit();
|
||||
size_t get_white_peers_count(){CRITICAL_REGION_LOCAL(m_peerlist_lock); return m_peers_white.size();}
|
||||
size_t get_gray_peers_count(){CRITICAL_REGION_LOCAL(m_peerlist_lock); return m_peers_gray.size();}
|
||||
bool merge_peerlist(const std::list<peerlist_entry>& outer_bs);
|
||||
bool get_peerlist_head(std::list<peerlist_entry>& bs_head, uint32_t depth = P2P_DEFAULT_PEERS_IN_HANDSHAKE);
|
||||
bool get_peerlist_full(std::list<peerlist_entry>& pl_gray, std::list<peerlist_entry>& pl_white);
|
||||
bool get_white_peer_by_index(peerlist_entry& p, size_t i);
|
||||
bool get_gray_peer_by_index(peerlist_entry& p, size_t i);
|
||||
bool append_with_peer_white(const peerlist_entry& pr);
|
||||
bool append_with_peer_gray(const peerlist_entry& pr);
|
||||
bool set_peer_just_seen(peerid_type peer, uint32_t ip, uint32_t port);
|
||||
bool set_peer_just_seen(peerid_type peer, const net_address& addr);
|
||||
bool set_peer_unreachable(const peerlist_entry& pr);
|
||||
bool is_ip_allowed(uint32_t ip);
|
||||
void trim_white_peerlist();
|
||||
void trim_gray_peerlist();
|
||||
|
||||
|
||||
private:
|
||||
struct by_time{};
|
||||
struct by_id{};
|
||||
struct by_addr{};
|
||||
|
||||
struct modify_all_but_id
|
||||
{
|
||||
modify_all_but_id(const peerlist_entry& ple):m_ple(ple){}
|
||||
void operator()(peerlist_entry& e)
|
||||
{
|
||||
e.id = m_ple.id;
|
||||
}
|
||||
private:
|
||||
const peerlist_entry& m_ple;
|
||||
};
|
||||
|
||||
struct modify_all
|
||||
{
|
||||
modify_all(const peerlist_entry& ple):m_ple(ple){}
|
||||
void operator()(peerlist_entry& e)
|
||||
{
|
||||
e = m_ple;
|
||||
}
|
||||
private:
|
||||
const peerlist_entry& m_ple;
|
||||
};
|
||||
|
||||
struct modify_last_seen
|
||||
{
|
||||
modify_last_seen(time_t last_seen):m_last_seen(last_seen){}
|
||||
void operator()(peerlist_entry& e)
|
||||
{
|
||||
e.last_seen = m_last_seen;
|
||||
}
|
||||
private:
|
||||
time_t m_last_seen;
|
||||
};
|
||||
|
||||
|
||||
typedef boost::multi_index_container<
|
||||
peerlist_entry,
|
||||
boost::multi_index::indexed_by<
|
||||
// access by peerlist_entry::net_adress
|
||||
boost::multi_index::ordered_unique<boost::multi_index::tag<by_addr>, boost::multi_index::member<peerlist_entry,net_address,&peerlist_entry::adr> >,
|
||||
// sort by peerlist_entry::last_seen<
|
||||
boost::multi_index::ordered_non_unique<boost::multi_index::tag<by_time>, boost::multi_index::member<peerlist_entry,time_t,&peerlist_entry::last_seen> >
|
||||
>
|
||||
> peers_indexed;
|
||||
|
||||
typedef boost::multi_index_container<
|
||||
peerlist_entry,
|
||||
boost::multi_index::indexed_by<
|
||||
// access by peerlist_entry::id<
|
||||
boost::multi_index::ordered_unique<boost::multi_index::tag<by_id>, boost::multi_index::member<peerlist_entry,uint64_t,&peerlist_entry::id> >,
|
||||
// access by peerlist_entry::net_adress
|
||||
boost::multi_index::ordered_unique<boost::multi_index::tag<by_addr>, boost::multi_index::member<peerlist_entry,net_address,&peerlist_entry::adr> >,
|
||||
// sort by peerlist_entry::last_seen<
|
||||
boost::multi_index::ordered_non_unique<boost::multi_index::tag<by_time>, boost::multi_index::member<peerlist_entry,time_t,&peerlist_entry::last_seen> >
|
||||
>
|
||||
> peers_indexed_old;
|
||||
public:
|
||||
|
||||
template <class Archive, class t_version_type>
|
||||
void serialize(Archive &a, const t_version_type ver)
|
||||
{
|
||||
if(ver < 3)
|
||||
return;
|
||||
CRITICAL_REGION_LOCAL(m_peerlist_lock);
|
||||
if(ver < 4)
|
||||
{
|
||||
//loading data from old storage
|
||||
peers_indexed_old pio;
|
||||
a & pio;
|
||||
peers_indexed_from_old(pio, m_peers_white);
|
||||
return;
|
||||
}
|
||||
a & m_peers_white;
|
||||
a & m_peers_gray;
|
||||
}
|
||||
|
||||
private:
|
||||
bool peers_indexed_from_old(const peers_indexed_old& pio, peers_indexed& pi);
|
||||
|
||||
friend class boost::serialization::access;
|
||||
epee::critical_section m_peerlist_lock;
|
||||
std::string m_config_folder;
|
||||
bool m_allow_local_ip;
|
||||
|
||||
|
||||
peers_indexed m_peers_gray;
|
||||
peers_indexed m_peers_white;
|
||||
};
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
inline
|
||||
bool peerlist_manager::init(bool allow_local_ip)
|
||||
{
|
||||
m_allow_local_ip = allow_local_ip;
|
||||
return true;
|
||||
}
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
inline
|
||||
bool peerlist_manager::deinit()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
inline
|
||||
bool peerlist_manager::peers_indexed_from_old(const peers_indexed_old& pio, peers_indexed& pi)
|
||||
{
|
||||
for(auto x: pio)
|
||||
{
|
||||
auto by_addr_it = pi.get<by_addr>().find(x.adr);
|
||||
if(by_addr_it == pi.get<by_addr>().end())
|
||||
{
|
||||
pi.insert(x);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
inline void peerlist_manager::trim_white_peerlist()
|
||||
{
|
||||
while(m_peers_gray.size() > P2P_LOCAL_GRAY_PEERLIST_LIMIT)
|
||||
{
|
||||
peers_indexed::index<by_time>::type& sorted_index=m_peers_gray.get<by_time>();
|
||||
sorted_index.erase(sorted_index.begin());
|
||||
}
|
||||
}
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
inline void peerlist_manager::trim_gray_peerlist()
|
||||
{
|
||||
while(m_peers_white.size() > P2P_LOCAL_WHITE_PEERLIST_LIMIT)
|
||||
{
|
||||
peers_indexed::index<by_time>::type& sorted_index=m_peers_white.get<by_time>();
|
||||
sorted_index.erase(sorted_index.begin());
|
||||
}
|
||||
}
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
inline
|
||||
bool peerlist_manager::merge_peerlist(const std::list<peerlist_entry>& outer_bs)
|
||||
{
|
||||
CRITICAL_REGION_LOCAL(m_peerlist_lock);
|
||||
BOOST_FOREACH(const peerlist_entry& be, outer_bs)
|
||||
{
|
||||
append_with_peer_gray(be);
|
||||
}
|
||||
// delete extra elements
|
||||
trim_gray_peerlist();
|
||||
return true;
|
||||
}
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
inline
|
||||
bool peerlist_manager::get_white_peer_by_index(peerlist_entry& p, size_t i)
|
||||
{
|
||||
CRITICAL_REGION_LOCAL(m_peerlist_lock);
|
||||
if(i >= m_peers_white.size())
|
||||
return false;
|
||||
|
||||
peers_indexed::index<by_time>::type& by_time_index = m_peers_white.get<by_time>();
|
||||
p = *epee::misc_utils::move_it_backward(--by_time_index.end(), i);
|
||||
return true;
|
||||
}
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
inline
|
||||
bool peerlist_manager::get_gray_peer_by_index(peerlist_entry& p, size_t i)
|
||||
{
|
||||
CRITICAL_REGION_LOCAL(m_peerlist_lock);
|
||||
if(i >= m_peers_gray.size())
|
||||
return false;
|
||||
|
||||
peers_indexed::index<by_time>::type& by_time_index = m_peers_gray.get<by_time>();
|
||||
p = *epee::misc_utils::move_it_backward(--by_time_index.end(), i);
|
||||
return true;
|
||||
}
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
inline
|
||||
bool peerlist_manager::is_ip_allowed(uint32_t ip)
|
||||
{
|
||||
//never allow loopback ip
|
||||
if(epee::net_utils::is_ip_loopback(ip))
|
||||
return false;
|
||||
|
||||
if(!m_allow_local_ip && epee::net_utils::is_ip_local(ip))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
inline
|
||||
bool peerlist_manager::get_peerlist_head(std::list<peerlist_entry>& bs_head, uint32_t depth)
|
||||
{
|
||||
|
||||
CRITICAL_REGION_LOCAL(m_peerlist_lock);
|
||||
peers_indexed::index<by_time>::type& by_time_index=m_peers_white.get<by_time>();
|
||||
uint32_t cnt = 0;
|
||||
BOOST_REVERSE_FOREACH(const peers_indexed::value_type& vl, by_time_index)
|
||||
{
|
||||
if(!vl.last_seen)
|
||||
continue;
|
||||
bs_head.push_back(vl);
|
||||
if(cnt++ > depth)
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
inline
|
||||
bool peerlist_manager::get_peerlist_full(std::list<peerlist_entry>& pl_gray, std::list<peerlist_entry>& pl_white)
|
||||
{
|
||||
CRITICAL_REGION_LOCAL(m_peerlist_lock);
|
||||
peers_indexed::index<by_time>::type& by_time_index_gr=m_peers_gray.get<by_time>();
|
||||
BOOST_REVERSE_FOREACH(const peers_indexed::value_type& vl, by_time_index_gr)
|
||||
{
|
||||
pl_gray.push_back(vl);
|
||||
}
|
||||
|
||||
peers_indexed::index<by_time>::type& by_time_index_wt=m_peers_white.get<by_time>();
|
||||
BOOST_REVERSE_FOREACH(const peers_indexed::value_type& vl, by_time_index_wt)
|
||||
{
|
||||
pl_white.push_back(vl);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
inline
|
||||
bool peerlist_manager::set_peer_just_seen(peerid_type peer, uint32_t ip, uint32_t port)
|
||||
{
|
||||
net_address addr;
|
||||
addr.ip = ip;
|
||||
addr.port = port;
|
||||
return set_peer_just_seen(peer, addr);
|
||||
}
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
inline
|
||||
bool peerlist_manager::set_peer_just_seen(peerid_type peer, const net_address& addr)
|
||||
{
|
||||
TRY_ENTRY();
|
||||
CRITICAL_REGION_LOCAL(m_peerlist_lock);
|
||||
//find in white list
|
||||
peerlist_entry ple;
|
||||
ple.adr = addr;
|
||||
ple.id = peer;
|
||||
ple.last_seen = time(NULL);
|
||||
return append_with_peer_white(ple);
|
||||
CATCH_ENTRY_L0("peerlist_manager::set_peer_just_seen()", false);
|
||||
}
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
inline
|
||||
bool peerlist_manager::append_with_peer_white(const peerlist_entry& ple)
|
||||
{
|
||||
TRY_ENTRY();
|
||||
if(!is_ip_allowed(ple.adr.ip))
|
||||
return true;
|
||||
|
||||
CRITICAL_REGION_LOCAL(m_peerlist_lock);
|
||||
//find in white list
|
||||
auto by_addr_it_wt = m_peers_white.get<by_addr>().find(ple.adr);
|
||||
if(by_addr_it_wt == m_peers_white.get<by_addr>().end())
|
||||
{
|
||||
//put new record into white list
|
||||
m_peers_white.insert(ple);
|
||||
trim_white_peerlist();
|
||||
}else
|
||||
{
|
||||
//update record in white list
|
||||
m_peers_white.replace(by_addr_it_wt, ple);
|
||||
}
|
||||
//remove from gray list, if need
|
||||
auto by_addr_it_gr = m_peers_gray.get<by_addr>().find(ple.adr);
|
||||
if(by_addr_it_gr != m_peers_gray.get<by_addr>().end())
|
||||
{
|
||||
m_peers_gray.erase(by_addr_it_gr);
|
||||
}
|
||||
return true;
|
||||
CATCH_ENTRY_L0("peerlist_manager::append_with_peer_white()", false);
|
||||
}
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
inline
|
||||
bool peerlist_manager::append_with_peer_gray(const peerlist_entry& ple)
|
||||
{
|
||||
TRY_ENTRY();
|
||||
if(!is_ip_allowed(ple.adr.ip))
|
||||
return true;
|
||||
|
||||
CRITICAL_REGION_LOCAL(m_peerlist_lock);
|
||||
//find in white list
|
||||
auto by_addr_it_wt = m_peers_white.get<by_addr>().find(ple.adr);
|
||||
if(by_addr_it_wt != m_peers_white.get<by_addr>().end())
|
||||
return true;
|
||||
|
||||
//update gray list
|
||||
auto by_addr_it_gr = m_peers_gray.get<by_addr>().find(ple.adr);
|
||||
if(by_addr_it_gr == m_peers_gray.get<by_addr>().end())
|
||||
{
|
||||
//put new record into white list
|
||||
m_peers_gray.insert(ple);
|
||||
trim_gray_peerlist();
|
||||
}else
|
||||
{
|
||||
//update record in white list
|
||||
m_peers_gray.replace(by_addr_it_gr, ple);
|
||||
}
|
||||
return true;
|
||||
CATCH_ENTRY_L0("peerlist_manager::append_with_peer_gray()", false);
|
||||
return true;
|
||||
}
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
}
|
||||
|
||||
BOOST_CLASS_VERSION(nodetool::peerlist_manager, 4)
|
|
@ -0,0 +1,28 @@
|
|||
// Copyright (c) 2012-2013 The Cryptonote developers
|
||||
// Distributed under the MIT/X11 software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace serialization
|
||||
{
|
||||
//BOOST_CLASS_VERSION(odetool::net_adress, 1)
|
||||
template <class Archive, class ver_type>
|
||||
inline void serialize(Archive &a, nodetool::net_address& na, const ver_type ver)
|
||||
{
|
||||
a & na.ip;
|
||||
a & na.port;
|
||||
}
|
||||
|
||||
|
||||
template <class Archive, class ver_type>
|
||||
inline void serialize(Archive &a, nodetool::peerlist_entry& pl, const ver_type ver)
|
||||
{
|
||||
a & pl.adr;
|
||||
a & pl.id;
|
||||
a & pl.last_seen;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
// Copyright (c) 2012-2013 The Cryptonote developers
|
||||
// Distributed under the MIT/X11 software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace nodetool
|
||||
{
|
||||
const static boost::uuids::uuid BYTECOIN_NETWORK = { { 0x05 ,0x4b, 0x77, 0x09, 0xa5, 0xa3 , 0x4c, 0x34, 0xba, 0xa2, 0x0e, 0x25, 0xf9, 0xad, 0x40, 0x53} };
|
||||
}
|
|
@ -0,0 +1,315 @@
|
|||
// Copyright (c) 2012-2013 The Cryptonote developers
|
||||
// Distributed under the MIT/X11 software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <boost/uuid/uuid.hpp>
|
||||
#include "serialization/keyvalue_serialization.h"
|
||||
#include "misc_language.h"
|
||||
#include "cryptonote_config.h"
|
||||
#include "crypto/crypto.h"
|
||||
|
||||
namespace nodetool
|
||||
{
|
||||
typedef boost::uuids::uuid uuid;
|
||||
typedef uint64_t peerid_type;
|
||||
|
||||
#pragma pack (push, 1)
|
||||
|
||||
struct net_address
|
||||
{
|
||||
uint32_t ip;
|
||||
uint32_t port;
|
||||
};
|
||||
|
||||
struct peerlist_entry
|
||||
{
|
||||
net_address adr;
|
||||
peerid_type id;
|
||||
time_t last_seen;
|
||||
};
|
||||
|
||||
struct connection_entry
|
||||
{
|
||||
net_address adr;
|
||||
peerid_type id;
|
||||
bool is_income;
|
||||
};
|
||||
|
||||
#pragma pack(pop)
|
||||
|
||||
inline
|
||||
bool operator < (const net_address& a, const net_address& b)
|
||||
{
|
||||
return epee::misc_utils::is_less_as_pod(a, b);
|
||||
}
|
||||
|
||||
inline
|
||||
bool operator == (const net_address& a, const net_address& b)
|
||||
{
|
||||
return memcmp(&a, &b, sizeof(a)) == 0;
|
||||
}
|
||||
inline
|
||||
std::string print_peerlist_to_string(const std::list<peerlist_entry>& pl)
|
||||
{
|
||||
time_t now_time = 0;
|
||||
time(&now_time);
|
||||
std::stringstream ss;
|
||||
ss << std::setfill ('0') << std::setw (8) << std::hex << std::noshowbase;
|
||||
BOOST_FOREACH(const peerlist_entry& pe, pl)
|
||||
{
|
||||
ss << pe.id << "\t" << epee::string_tools::get_ip_string_from_int32(pe.adr.ip) << ":" << boost::lexical_cast<std::string>(pe.adr.port) << " \tlast_seen: " << epee::misc_utils::get_time_interval_string(now_time - pe.last_seen) << std::endl;
|
||||
}
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
|
||||
struct network_config
|
||||
{
|
||||
BEGIN_KV_SERIALIZE_MAP()
|
||||
KV_SERIALIZE(connections_count)
|
||||
KV_SERIALIZE(handshake_interval)
|
||||
KV_SERIALIZE(packet_max_size)
|
||||
KV_SERIALIZE(config_id)
|
||||
END_KV_SERIALIZE_MAP()
|
||||
|
||||
uint32_t connections_count;
|
||||
uint32_t connection_timeout;
|
||||
uint32_t ping_connection_timeout;
|
||||
uint32_t handshake_interval;
|
||||
uint32_t packet_max_size;
|
||||
uint32_t config_id;
|
||||
uint32_t send_peerlist_sz;
|
||||
};
|
||||
|
||||
struct basic_node_data
|
||||
{
|
||||
uuid network_id;
|
||||
uint64_t local_time;
|
||||
uint32_t my_port;
|
||||
peerid_type peer_id;
|
||||
|
||||
BEGIN_KV_SERIALIZE_MAP()
|
||||
KV_SERIALIZE_VAL_POD_AS_BLOB(network_id)
|
||||
KV_SERIALIZE(peer_id)
|
||||
KV_SERIALIZE(local_time)
|
||||
KV_SERIALIZE(my_port)
|
||||
END_KV_SERIALIZE_MAP()
|
||||
};
|
||||
|
||||
|
||||
#define P2P_COMMANDS_POOL_BASE 1000
|
||||
|
||||
/************************************************************************/
|
||||
/* */
|
||||
/************************************************************************/
|
||||
template<class t_playload_type>
|
||||
struct COMMAND_HANDSHAKE_T
|
||||
{
|
||||
const static int ID = P2P_COMMANDS_POOL_BASE + 1;
|
||||
|
||||
struct request
|
||||
{
|
||||
basic_node_data node_data;
|
||||
t_playload_type payload_data;
|
||||
|
||||
BEGIN_KV_SERIALIZE_MAP()
|
||||
KV_SERIALIZE(node_data)
|
||||
KV_SERIALIZE(payload_data)
|
||||
END_KV_SERIALIZE_MAP()
|
||||
};
|
||||
|
||||
struct response
|
||||
{
|
||||
basic_node_data node_data;
|
||||
t_playload_type payload_data;
|
||||
std::list<peerlist_entry> local_peerlist;
|
||||
|
||||
BEGIN_KV_SERIALIZE_MAP()
|
||||
KV_SERIALIZE(node_data)
|
||||
KV_SERIALIZE(payload_data)
|
||||
KV_SERIALIZE_CONTAINER_POD_AS_BLOB(local_peerlist)
|
||||
END_KV_SERIALIZE_MAP()
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
/************************************************************************/
|
||||
/* */
|
||||
/************************************************************************/
|
||||
template<class t_playload_type>
|
||||
struct COMMAND_TIMED_SYNC_T
|
||||
{
|
||||
const static int ID = P2P_COMMANDS_POOL_BASE + 2;
|
||||
|
||||
struct request
|
||||
{
|
||||
t_playload_type payload_data;
|
||||
BEGIN_KV_SERIALIZE_MAP()
|
||||
KV_SERIALIZE(payload_data)
|
||||
END_KV_SERIALIZE_MAP()
|
||||
};
|
||||
|
||||
struct response
|
||||
{
|
||||
uint64_t local_time;
|
||||
t_playload_type payload_data;
|
||||
std::list<peerlist_entry> local_peerlist;
|
||||
|
||||
BEGIN_KV_SERIALIZE_MAP()
|
||||
KV_SERIALIZE(local_time)
|
||||
KV_SERIALIZE(payload_data)
|
||||
KV_SERIALIZE_CONTAINER_POD_AS_BLOB(local_peerlist)
|
||||
END_KV_SERIALIZE_MAP()
|
||||
};
|
||||
};
|
||||
|
||||
/************************************************************************/
|
||||
/* */
|
||||
/************************************************************************/
|
||||
|
||||
struct COMMAND_PING
|
||||
{
|
||||
/*
|
||||
Used to make "callback" connection, to be sure that opponent node
|
||||
have accessible connection point. Only other nodes can add peer to peerlist,
|
||||
and ONLY in case when peer has accepted connection and answered to ping.
|
||||
*/
|
||||
const static int ID = P2P_COMMANDS_POOL_BASE + 3;
|
||||
|
||||
#define PING_OK_RESPONSE_STATUS_TEXT "OK"
|
||||
|
||||
struct request
|
||||
{
|
||||
/*actually we don't need to send any real data*/
|
||||
|
||||
BEGIN_KV_SERIALIZE_MAP()
|
||||
END_KV_SERIALIZE_MAP()
|
||||
};
|
||||
|
||||
struct response
|
||||
{
|
||||
std::string status;
|
||||
peerid_type peer_id;
|
||||
|
||||
BEGIN_KV_SERIALIZE_MAP()
|
||||
KV_SERIALIZE(status)
|
||||
KV_SERIALIZE(peer_id)
|
||||
END_KV_SERIALIZE_MAP()
|
||||
};
|
||||
};
|
||||
|
||||
struct proof_of_trust
|
||||
{
|
||||
peerid_type peer_id;
|
||||
uint64_t time;
|
||||
crypto::signature sign;
|
||||
|
||||
BEGIN_KV_SERIALIZE_MAP()
|
||||
KV_SERIALIZE(peer_id)
|
||||
KV_SERIALIZE(time)
|
||||
KV_SERIALIZE_VAL_POD_AS_BLOB(sign)
|
||||
END_KV_SERIALIZE_MAP()
|
||||
};
|
||||
|
||||
|
||||
#ifdef ALLOW_DEBUG_COMMANDS
|
||||
//These commands are considered as insecure, and made in debug purposes for a limited lifetime.
|
||||
//Anyone who feel unsafe with this commands can disable the ALLOW_GET_STAT_COMMAND macro.
|
||||
|
||||
|
||||
template<class payload_stat_info>
|
||||
struct COMMAND_REQUEST_STAT_INFO_T
|
||||
{
|
||||
const static int ID = P2P_COMMANDS_POOL_BASE + 4;
|
||||
|
||||
struct request
|
||||
{
|
||||
proof_of_trust tr;
|
||||
BEGIN_KV_SERIALIZE_MAP()
|
||||
KV_SERIALIZE(tr)
|
||||
END_KV_SERIALIZE_MAP()
|
||||
};
|
||||
|
||||
struct response
|
||||
{
|
||||
std::string version;
|
||||
std::string os_version;
|
||||
uint64_t connections_count;
|
||||
uint64_t incoming_connections_count;
|
||||
payload_stat_info payload_info;
|
||||
|
||||
BEGIN_KV_SERIALIZE_MAP()
|
||||
KV_SERIALIZE(version)
|
||||
KV_SERIALIZE(os_version)
|
||||
KV_SERIALIZE(connections_count)
|
||||
KV_SERIALIZE(incoming_connections_count)
|
||||
KV_SERIALIZE(payload_info)
|
||||
END_KV_SERIALIZE_MAP()
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
/************************************************************************/
|
||||
/* */
|
||||
/************************************************************************/
|
||||
struct COMMAND_REQUEST_NETWORK_STATE
|
||||
{
|
||||
const static int ID = P2P_COMMANDS_POOL_BASE + 5;
|
||||
|
||||
struct request
|
||||
{
|
||||
proof_of_trust tr;
|
||||
BEGIN_KV_SERIALIZE_MAP()
|
||||
KV_SERIALIZE(tr)
|
||||
END_KV_SERIALIZE_MAP()
|
||||
};
|
||||
|
||||
struct response
|
||||
{
|
||||
std::list<peerlist_entry> local_peerlist_white;
|
||||
std::list<peerlist_entry> local_peerlist_gray;
|
||||
std::list<connection_entry> connections_list;
|
||||
peerid_type my_id;
|
||||
uint64_t local_time;
|
||||
BEGIN_KV_SERIALIZE_MAP()
|
||||
KV_SERIALIZE_CONTAINER_POD_AS_BLOB(local_peerlist_white)
|
||||
KV_SERIALIZE_CONTAINER_POD_AS_BLOB(local_peerlist_gray)
|
||||
KV_SERIALIZE_CONTAINER_POD_AS_BLOB(connections_list)
|
||||
KV_SERIALIZE(my_id)
|
||||
KV_SERIALIZE(local_time)
|
||||
END_KV_SERIALIZE_MAP()
|
||||
};
|
||||
};
|
||||
|
||||
/************************************************************************/
|
||||
/* */
|
||||
/************************************************************************/
|
||||
struct COMMAND_REQUEST_PEER_ID
|
||||
{
|
||||
const static int ID = P2P_COMMANDS_POOL_BASE + 6;
|
||||
|
||||
struct request
|
||||
{
|
||||
BEGIN_KV_SERIALIZE_MAP()
|
||||
END_KV_SERIALIZE_MAP()
|
||||
};
|
||||
|
||||
struct response
|
||||
{
|
||||
peerid_type my_id;
|
||||
|
||||
BEGIN_KV_SERIALIZE_MAP()
|
||||
KV_SERIALIZE(my_id)
|
||||
END_KV_SERIALIZE_MAP()
|
||||
};
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
// Copyright (c) 2012-2013 The Cryptonote developers
|
||||
// Distributed under the MIT/X11 software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "targetver.h"
|
||||
|
||||
|
||||
#if !defined(__GNUC__)
|
||||
#define _CRTDBG_MAP_ALLOC
|
||||
#include <stdlib.h>
|
||||
#include <crtdbg.h>
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
|
||||
#define BOOST_FILESYSTEM_VERSION 3
|
||||
#define ENABLE_RELEASE_LOGGING
|
||||
#include "log_opt_defs.h"
|
||||
#include "misc_log_ex.h"
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue