aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/salticidae/msg.h12
-rw-r--r--include/salticidae/network.h217
-rw-r--r--include/salticidae/util.h5
-rw-r--r--src/network.cpp49
-rw-r--r--test/test_msg.cpp2
-rw-r--r--test/test_p2p.cpp65
-rw-r--r--test/test_p2p_tls.cpp2
7 files changed, 241 insertions, 111 deletions
diff --git a/include/salticidae/msg.h b/include/salticidae/msg.h
index a81a5ae..11cf309 100644
--- a/include/salticidae/msg.h
+++ b/include/salticidae/msg.h
@@ -58,14 +58,10 @@ class MsgBase {
mutable bool no_payload;
public:
- MsgBase(): magic(0x0), opcode(0xff), no_payload(true) {}
-
- template<typename MsgType,
- typename = typename std::enable_if<
- !std::is_same<MsgType, MsgBase>::value &&
- !std::is_same<MsgType, bytearray_t>::value &&
- !std::is_same<MsgType, DataStream>::value>::type>
- MsgBase(const MsgType &msg): magic(0x0) {
+ MsgBase(uint32_t magic = 0x0): magic(magic), opcode(0xff), no_payload(true) {}
+
+ template<typename MsgType>
+ MsgBase(const MsgType &msg, uint32_t magic): magic(magic) {
set_opcode(MsgType::opcode);
set_payload(std::move(msg.serialized));
set_checksum();
diff --git a/include/salticidae/network.h b/include/salticidae/network.h
index 37ecc75..eff5369 100644
--- a/include/salticidae/network.h
+++ b/include/salticidae/network.h
@@ -129,6 +129,7 @@ class MsgNetwork: public ConnPool {
queue_t incoming_msgs;
protected:
+ const uint32_t msg_magic;
ConnPool::Conn *create_conn() override { return new Conn(); }
void on_read(const ConnPool::conn_t &) override;
@@ -159,6 +160,7 @@ class MsgNetwork: public ConnPool {
size_t _max_msg_size;
size_t _max_msg_queue_size;
size_t _burst_size;
+ uint32_t _msg_magic;
public:
Config(): Config(ConnPool::Config()) {}
@@ -166,7 +168,8 @@ class MsgNetwork: public ConnPool {
ConnPool::Config(config),
_max_msg_size(1024),
_max_msg_queue_size(65536),
- _burst_size(1000) {}
+ _burst_size(1000),
+ _msg_magic(0x0) {}
Config &max_msg_size(size_t x) {
_max_msg_size = x;
@@ -182,6 +185,10 @@ class MsgNetwork: public ConnPool {
_burst_size = x;
return *this;
}
+
+ Config &msg_magic(uint32_t x) {
+ _msg_magic = x;
+ }
};
virtual ~MsgNetwork() { stop(); }
@@ -189,7 +196,8 @@ class MsgNetwork: public ConnPool {
MsgNetwork(const EventContext &ec, const Config &config):
ConnPool(ec, config),
max_msg_size(config._max_msg_size),
- max_msg_queue_size(config._max_msg_queue_size) {
+ max_msg_queue_size(config._max_msg_queue_size),
+ msg_magic(config._msg_magic) {
incoming_msgs.set_capacity(max_msg_queue_size);
incoming_msgs.reg_handler(ec, [this, burst_size=config._burst_size](queue_t &q) {
std::pair<Msg, conn_t> item;
@@ -293,6 +301,37 @@ class ClientNetwork: public MsgNetwork<OpcodeType> {
inline int32_t _send_msg_deferred(Msg &&msg, const NetAddr &addr);
};
+struct PeerId: public uint256_t {
+ using uint256_t::uint256_t;
+ PeerId(const NetAddr &addr) {
+ *(static_cast<uint256_t *>(this)) = salticidae::get_hash(addr);
+ }
+
+ PeerId(const X509 &cert) {
+ *(static_cast<uint256_t *>(this)) = salticidae::get_hash(cert.get_der());
+ }
+};
+
+}
+
+namespace std {
+ template <>
+ struct hash<salticidae::PeerId> {
+ size_t operator()(const salticidae::PeerId &p) const {
+ return hash<salticidae::uint256_t>()(p);
+ }
+ };
+
+ template <>
+ struct hash<const salticidae::PeerId> {
+ size_t operator()(const salticidae::PeerId &p) const {
+ return hash<salticidae::uint256_t>()(p);
+ }
+ };
+}
+
+namespace salticidae {
+
/** Peer-to-peer network where any two nodes could hold a bi-diretional message
* channel, established by either side. */
template<typename OpcodeType = uint8_t,
@@ -344,20 +383,6 @@ class PeerNetwork: public MsgNetwork<OpcodeType> {
using peer_callback_t = std::function<void(const conn_t &peer_conn, bool connected)>;
using unknown_peer_callback_t = std::function<void(const NetAddr &claimed_addr, const X509 *cert)>;
- struct PeerId: public uint256_t {
- PeerId(const NetAddr &addr) {
- DataStream tmp;
- tmp << addr;
- *(static_cast<uint256_t *>(this)) = tmp.get_hash();
- }
-
- PeerId(const X509 &cert) {
- DataStream tmp;
- tmp << cert.get_der();
- *(static_cast<uint256_t *>(this)) = tmp.get_hash();
- }
- };
-
private:
struct Peer {
@@ -425,6 +450,7 @@ class PeerNetwork: public MsgNetwork<OpcodeType> {
NetAddr listen_addr;
bool allow_unknown_peer;
uint256_t my_nonce;
+ uint256_t passive_nonce;
struct MsgPing {
static const OpcodeType opcode;
@@ -460,7 +486,7 @@ class PeerNetwork: public MsgNetwork<OpcodeType> {
conn_t start_active_conn(const NetAddr &addr);
static void tcall_reset_timeout(ConnPool::Worker *worker,
const conn_t &conn, double timeout);
- inline conn_t _get_peer_conn(const NetAddr &addr) const;
+ inline conn_t _get_peer_conn(const PeerId &peer) const;
protected:
ConnPool::Conn *create_conn() override { return new Conn(); }
@@ -522,6 +548,9 @@ class PeerNetwork: public MsgNetwork<OpcodeType> {
ping_period(config._ping_period),
conn_timeout(config._conn_timeout),
allow_unknown_peer(config._allow_unknown_peer) {
+ uint64_t ones[4];
+ memset(ones, 0xff, 32);
+ passive_nonce.load((uint8_t *)ones);
this->reg_handler(generic_bind(&PeerNetwork::ping_handler, this, _1, _2));
this->reg_handler(generic_bind(&PeerNetwork::pong_handler, this, _1, _2));
}
@@ -529,26 +558,26 @@ class PeerNetwork: public MsgNetwork<OpcodeType> {
virtual ~PeerNetwork() { this->stop(); }
/* register a peer as known */
- int32_t add_peer(const PeerId &pid);
+ int32_t add_peer(const PeerId &peer);
/* set the peer's public IP */
- int32_t set_peer_addr(const PeerId &pid, const NetAddr &addr);
+ int32_t set_peer_addr(const PeerId &peer, const NetAddr &addr);
/* try to connect to the peer: once (ntry = 1), indefinitely (ntry = -1), give up retry (ntry = 0) */
- int32_t try_conn_peer(const PeerId &pid, ssize_t ntry = -1, double retry_delay = 2);
+ int32_t conn_peer(const PeerId &peer, ssize_t ntry = -1, double retry_delay = 2);
/* unregister the peer */
- int32_t del_peer(const PeerId &pid);
- bool has_peer(const PeerId &pid) const;
+ int32_t del_peer(const PeerId &peer);
+ bool has_peer(const PeerId &peer) const;
size_t get_npending() const;
conn_t get_peer_conn(const PeerId &addr) const;
using MsgNet::send_msg;
template<typename MsgType>
- inline bool send_msg(const MsgType &msg, const NetAddr &addr);
- inline bool _send_msg(const Msg &msg, const NetAddr &addr);
+ inline bool send_msg(const MsgType &msg, const PeerId &peer);
+ inline bool _send_msg(const Msg &msg, const PeerId &peer);
template<typename MsgType>
- inline int32_t send_msg_deferred(MsgType &&msg, const NetAddr &addr);
- inline int32_t _send_msg_deferred(Msg &&msg, const NetAddr &addr);
+ inline int32_t send_msg_deferred(MsgType &&msg, const PeerId &peer);
+ inline int32_t _send_msg_deferred(Msg &&msg, const PeerId &peer);
template<typename MsgType>
- inline int32_t multicast_msg(MsgType &&msg, const std::vector<NetAddr> &addrs);
- inline int32_t _multicast_msg(Msg &&msg, const std::vector<NetAddr> &addrs);
+ inline int32_t multicast_msg(MsgType &&msg, const std::vector<PeerId> &peers);
+ inline int32_t _multicast_msg(Msg &&msg, const std::vector<PeerId> &peers);
void listen(NetAddr listen_addr);
conn_t connect(const NetAddr &addr) = delete;
@@ -637,7 +666,7 @@ inline int32_t MsgNetwork<OpcodeType>::_send_msg_deferred(Msg &&msg, const conn_
template<typename OpcodeType>
template<typename MsgType>
inline bool MsgNetwork<OpcodeType>::send_msg(const MsgType &msg, const conn_t &conn) {
- return _send_msg(msg, conn);
+ return _send_msg(Msg(msg, msg_magic), conn);
}
template<typename OpcodeType>
@@ -700,11 +729,11 @@ void PeerNetwork<O, _, __>::on_teardown(const ConnPool::conn_t &_conn) {
auto p = conn->peer;
if (!p) return;
assert(conn == p->conn);
+ p->connected = false;
+ p->conn = nullptr;
p->inbound_conn = nullptr;
p->outbound_conn = nullptr;
p->ev_ping_timer.del();
- p->connected = false;
- p->conn = nullptr;
this->user_tcall->async_call([this, conn](ThreadCall::Handle &) {
if (peer_cb) peer_cb(conn, false);
});
@@ -725,18 +754,21 @@ template<typename O, O _, O __>
void PeerNetwork<O, _, __>::Peer::update_conn(const conn_t &new_conn) {
if (conn != new_conn)
{
- conn->peer = nullptr;
- if (conn->is_terminated())
+ if (conn)
{
- for (;;)
+ conn->peer = nullptr;
+ if (conn->is_terminated())
{
- bytearray_t buff_seg = conn->send_buffer.move_pop();
- if (!buff_seg.size()) break;
- new_conn->write(std::move(buff_seg));
+ for (;;)
+ {
+ bytearray_t buff_seg = conn->send_buffer.move_pop();
+ if (!buff_seg.size()) break;
+ new_conn->write(std::move(buff_seg));
+ }
}
+ else
+ conn->get_net()->disp_terminate(conn);
}
- else
- this->disp_terminate(conn);
conn = new_conn;
}
}
@@ -791,10 +823,10 @@ void PeerNetwork<O, _, __>::finish_handshake(Peer *p) {
color_begin = TTY_COLOR_BLUE;
color_end = TTY_COLOR_RESET;
}
- SALTICIDAE_LOG_INFO("%sPeerNetwork: established connection %s <-> %s via %s",
+ SALTICIDAE_LOG_INFO("%sPeerNetwork: established connection %s <-> %s(%s)",
color_begin,
std::string(listen_addr).c_str(),
- std::string(p->addr).c_str(),
+ get_hex10(p->id).c_str(),
std::string(*(p->conn)).c_str(),
color_end);
}
@@ -823,11 +855,11 @@ typename PeerNetwork<O, _, __>::conn_t PeerNetwork<O, _, __>::start_active_conn(
}
template<typename O, O _, O __>
-inline typename PeerNetwork<O, _, __>::conn_t PeerNetwork<O, _, __>::_get_peer_conn(const NetAddr &addr) const {
- auto it = known_peers.find(addr);
+inline typename PeerNetwork<O, _, __>::conn_t PeerNetwork<O, _, __>::_get_peer_conn(const PeerId &pid) const {
+ auto it = known_peers.find(pid);
if (it == known_peers.end())
throw PeerNetworkError(SALTI_ERROR_PEER_NOT_EXIST);
- return it->second->peer_conn;
+ return it->second->conn;
}
/* end: functions invoked by the dispatcher */
@@ -843,7 +875,7 @@ void PeerNetwork<O, _, __>::ping_handler(MsgPing &&msg, const conn_t &conn) {
if (conn->get_mode() == Conn::ConnMode::PASSIVE)
{
pinfo_slock_t _g(known_peers_lock);
- auto pit = known_peers.find(msg.claimed_addr);
+ auto pit = known_peers.find(pid);
if (pit == known_peers.end())
{
this->user_tcall->async_call([this, addr=msg.claimed_addr, conn](ThreadCall::Handle &) {
@@ -856,7 +888,7 @@ void PeerNetwork<O, _, __>::ping_handler(MsgPing &&msg, const conn_t &conn) {
SALTICIDAE_LOG_INFO("%s inbound handshake from %s",
std::string(listen_addr).c_str(),
std::string(*conn).c_str());
- send_msg(MsgPong(listen_addr, my_nonce), conn);
+ send_msg(MsgPong(listen_addr, p->addr.is_null() ? passive_nonce : my_nonce), conn);
if (p->connected)
{
//conn->get_net()->disp_terminate(conn);
@@ -879,7 +911,7 @@ void PeerNetwork<O, _, __>::ping_handler(MsgPing &&msg, const conn_t &conn) {
this->disp_terminate(conn);
return;
}
- finish_handshake(p);
+ finish_handshake(p.get());
}
else
SALTICIDAE_LOG_WARN("unexpected inbound handshake from %s",
@@ -905,17 +937,16 @@ void PeerNetwork<O, _, __>::pong_handler(MsgPong &&msg, const conn_t &conn) {
if (conn->get_mode() == Conn::ConnMode::ACTIVE)
{
pinfo_ulock_t _g(known_peers_lock);
- SALTICIDAE_LOG_INFO("%s outbound handshake to %s",
- std::string(listen_addr).c_str(),
- std::string(*conn).c_str());
auto pit = known_peers.find(pid);
- assert(pit != known_peers.end());
- auto &p = pit->second;
- if (p->connected)
+ if (pit == known_peers.end())
{
- conn->get_net()->disp_terminate(conn);
+ this->disp_terminate(conn);
return;
}
+ SALTICIDAE_LOG_INFO("%s outbound handshake to %s",
+ std::string(listen_addr).c_str(),
+ std::string(*conn).c_str());
+ auto &p = pit->second;
auto &old_conn = p->outbound_conn;
if (old_conn && !old_conn->is_terminated())
{
@@ -940,7 +971,7 @@ void PeerNetwork<O, _, __>::pong_handler(MsgPong &&msg, const conn_t &conn) {
SALTICIDAE_LOG_WARN("multiple peer addresses share the same identity");
old_peer_addr = peer_addr;
p->reset_ping_timer();
- finish_handshake(p);
+ finish_handshake(p.get());
}
else
SALTICIDAE_LOG_WARN("unexpected outbound handshake from %s",
@@ -994,7 +1025,7 @@ int32_t PeerNetwork<O, _, __>::add_peer(const PeerId &pid) {
}
template<typename O, O _, O __>
-int32_t PeerNetwork<O, _, __>::try_conn_peer(const PeerId &pid, ssize_t ntry, double retry_delay) {
+int32_t PeerNetwork<O, _, __>::conn_peer(const PeerId &pid, ssize_t ntry, double retry_delay) {
auto id = this->gen_async_id();
this->disp_tcall->async_call([this, pid, ntry, retry_delay, id](ThreadCall::Handle &) {
try {
@@ -1003,13 +1034,15 @@ int32_t PeerNetwork<O, _, __>::try_conn_peer(const PeerId &pid, ssize_t ntry, do
if (it == known_peers.end())
throw PeerNetworkError(SALTI_ERROR_PEER_NOT_EXIST);
auto &p = it->second;
- if (p.addr.is_null())
+ if (p->addr.is_null())
throw PeerNetworkError(SALTI_ERROR_PEER_NOT_READY);
- // FIXME: ???
- if (p.peer_conn)
- p.peer_conn->disp_terminate();
- p.retry_delay = retry_delay;
- p.peer_conn = ntry ? start_active_conn(p.addr) : conn_t();
+ p->ntry = ntry;
+ p->retry_delay = retry_delay;
+ p->connected = false;
+ p->inbound_conn = nullptr;
+ p->outbound_conn = nullptr;
+ p->ev_ping_timer.del();
+ p->update_conn(ntry ? start_active_conn(p->addr) : conn_t());
} catch (const PeerNetworkError &) {
this->recoverable_error(std::current_exception(), id);
} catch (...) { this->disp_error_cb(std::current_exception()); }
@@ -1026,7 +1059,7 @@ int32_t PeerNetwork<O, _, __>::set_peer_addr(const PeerId &pid, const NetAddr &a
auto it = known_peers.find(pid);
if (it == known_peers.end())
throw PeerNetworkError(SALTI_ERROR_PEER_NOT_EXIST);
- it->addr = addr;
+ it->second->addr = addr;
} catch (const PeerNetworkError &) {
this->recoverable_error(std::current_exception(), id);
} catch (...) { this->disp_error_cb(std::current_exception()); }
@@ -1094,17 +1127,17 @@ size_t PeerNetwork<O, _, __>::get_npending() const {
template<typename O, O _, O __>
template<typename MsgType>
-inline int32_t PeerNetwork<O, _, __>::send_msg_deferred(MsgType &&msg, const NetAddr &addr) {
- return _send_msg_deferred(std::move(msg), addr);
+inline int32_t PeerNetwork<O, _, __>::send_msg_deferred(MsgType &&msg, const PeerId &pid) {
+ return _send_msg_deferred(std::move(msg), pid);
}
template<typename O, O _, O __>
-inline int32_t PeerNetwork<O, _, __>::_send_msg_deferred(Msg &&msg, const NetAddr &addr) {
+inline int32_t PeerNetwork<O, _, __>::_send_msg_deferred(Msg &&msg, const PeerId &pid) {
auto id = this->gen_async_id();
this->disp_tcall->async_call(
- [this, msg=std::move(msg), addr, id](ThreadCall::Handle &) {
+ [this, msg=std::move(msg), pid, id](ThreadCall::Handle &) {
try {
- if (!_send_msg(msg, addr))
+ if (!_send_msg(msg, pid))
throw PeerNetworkError(SALTI_ERROR_CONN_NOT_READY);
} catch (...) { this->recoverable_error(std::current_exception(), id); }
});
@@ -1113,31 +1146,31 @@ inline int32_t PeerNetwork<O, _, __>::_send_msg_deferred(Msg &&msg, const NetAdd
template<typename O, O _, O __>
template<typename MsgType>
-inline bool PeerNetwork<O, _, __>::send_msg(const MsgType &msg, const NetAddr &addr) {
- return _send_msg(msg, addr);
+inline bool PeerNetwork<O, _, __>::send_msg(const MsgType &msg, const PeerId &pid) {
+ return _send_msg(Msg(msg, this->msg_magic), pid);
}
template<typename O, O _, O __>
-inline bool PeerNetwork<O, _, __>::_send_msg(const Msg &msg, const NetAddr &addr) {
+inline bool PeerNetwork<O, _, __>::_send_msg(const Msg &msg, const PeerId &pid) {
pinfo_slock_t _g(known_peers_lock);
- return MsgNet::_send_msg(msg, _get_peer_conn(addr));
+ return MsgNet::_send_msg(msg, _get_peer_conn(pid));
}
template<typename O, O _, O __>
template<typename MsgType>
-inline int32_t PeerNetwork<O, _, __>::multicast_msg(MsgType &&msg, const std::vector<NetAddr> &addrs) {
- return _multicast_msg(MsgType(std::move(msg)), addrs);
+inline int32_t PeerNetwork<O, _, __>::multicast_msg(MsgType &&msg, const std::vector<PeerId> &pids) {
+ return _multicast_msg(MsgType(std::move(msg), this->msg_magic), pids);
}
template<typename O, O _, O __>
-inline int32_t PeerNetwork<O, _, __>::_multicast_msg(Msg &&msg, const std::vector<NetAddr> &addrs) {
+inline int32_t PeerNetwork<O, _, __>::_multicast_msg(Msg &&msg, const std::vector<PeerId> &pids) {
auto id = this->gen_async_id();
this->disp_tcall->async_call(
- [this, msg=std::move(msg), addrs, id](ThreadCall::Handle &) {
+ [this, msg=std::move(msg), pids, id](ThreadCall::Handle &) {
try {
bool succ = true;
- for (auto &addr: addrs)
- succ &= MsgNet::_send_msg(msg, _get_peer_conn(addr));
+ for (auto &pid: pids)
+ succ &= MsgNet::_send_msg(msg, _get_peer_conn(pid));
if (!succ) throw PeerNetworkError(SALTI_ERROR_CONN_NOT_READY);
} catch (...) { this->recoverable_error(std::current_exception(), id); }
});
@@ -1205,6 +1238,9 @@ const O PeerNetwork<O, _, OPCODE_PONG>::MsgPong::opcode = OPCODE_PONG;
}
#ifdef SALTICIDAE_CBINDINGS
+using peerid_t = salticidae::PeerId;
+using peerid_array_t = std::vector<peerid_t>;
+
using msgnetwork_t = salticidae::MsgNetwork<_opcode_t>;
using msgnetwork_config_t = msgnetwork_t::Config;
using msgnetwork_conn_t = msgnetwork_t::conn_t;
@@ -1220,6 +1256,9 @@ using clientnetwork_conn_t = clientnetwork_t::conn_t;
#else
#ifdef SALTICIDAE_CBINDINGS
+typedef struct peerid_t peerid_t;
+typedef struct peerid_t_array_t peerid_array_t;
+
typedef struct msgnetwork_t msgnetwork_t;
typedef struct msgnetwork_config_t msgnetwork_config_t;
typedef struct msgnetwork_conn_t msgnetwork_conn_t;
@@ -1301,6 +1340,14 @@ bool msgnetwork_conn_is_terminated(const msgnetwork_conn_t *conn);
/* PeerNetwork */
+//peerid_t *peerid_new();
+void peerid_free(const peerid_t *self);
+peerid_t *peerid_new_from_netaddr(const netaddr_t *addr);
+peerid_t *peerid_new_from_x509(const x509_t *cert);
+peerid_array_t *peerid_array_new();
+peerid_array_t *peerid_array_new_from_peerids(const peerid_t * const *pids, size_t npids);
+void peerid_array_free(peerid_array_t *self);
+
peernetwork_config_t *peernetwork_config_new();
void peernetwork_config_free(const peernetwork_config_t *self);
void peernetwork_config_ping_period(peernetwork_config_t *self, double t);
@@ -1310,10 +1357,10 @@ msgnetwork_config_t *peernetwork_config_as_msgnetwork_config(peernetwork_config_
peernetwork_t *peernetwork_new(const eventcontext_t *ec, const peernetwork_config_t *config, SalticidaeCError *err);
void peernetwork_free(const peernetwork_t *self);
-int32_t peernetwork_add_peer(peernetwork_t *self, const netaddr_t *addr);
-int32_t peernetwork_del_peer(peernetwork_t *self, const netaddr_t *addr);
-bool peernetwork_has_peer(const peernetwork_t *self, const netaddr_t *addr);
-const peernetwork_conn_t *peernetwork_get_peer_conn(const peernetwork_t *self, const netaddr_t *addr, SalticidaeCError *cerror);
+int32_t peernetwork_add_peer(peernetwork_t *self, const peerid_t *pid);
+int32_t peernetwork_del_peer(peernetwork_t *self, const peerid_t *pid);
+bool peernetwork_has_peer(const peernetwork_t *self, const peerid_t *pid);
+const peernetwork_conn_t *peernetwork_get_peer_conn(const peernetwork_t *self, const peerid_t *pid, SalticidaeCError *cerror);
msgnetwork_t *peernetwork_as_msgnetwork(peernetwork_t *self);
peernetwork_t *msgnetwork_as_peernetwork_unsafe(msgnetwork_t *self);
msgnetwork_conn_t *msgnetwork_conn_new_from_peernetwork_conn(const peernetwork_conn_t *conn);
@@ -1321,9 +1368,9 @@ peernetwork_conn_t *peernetwork_conn_new_from_msgnetwork_conn_unsafe(const msgne
peernetwork_conn_t *peernetwork_conn_copy(const peernetwork_conn_t *self);
netaddr_t *peernetwork_conn_get_peer_addr(const peernetwork_conn_t *self);
void peernetwork_conn_free(const peernetwork_conn_t *self);
-bool peernetwork_send_msg(peernetwork_t *self, const msg_t * msg, const netaddr_t *addr);
-int32_t peernetwork_send_msg_deferred_by_move(peernetwork_t *self, msg_t * _moved_msg, const netaddr_t *addr);
-int32_t peernetwork_multicast_msg_by_move(peernetwork_t *self, msg_t *_moved_msg, const netaddr_array_t *addrs);
+bool peernetwork_send_msg(peernetwork_t *self, const msg_t * msg, const peerid_t *peer);
+int32_t peernetwork_send_msg_deferred_by_move(peernetwork_t *self, msg_t * _moved_msg, const peerid_t *peer);
+int32_t peernetwork_multicast_msg_by_move(peernetwork_t *self, msg_t *_moved_msg, const peerid_array_t *peers);
void peernetwork_listen(peernetwork_t *self, const netaddr_t *listen_addr, SalticidaeCError *err);
typedef void (*peernetwork_peer_callback_t)(const peernetwork_conn_t *, bool connected, void *userdata);
diff --git a/include/salticidae/util.h b/include/salticidae/util.h
index b2ddd8e..cb09c0e 100644
--- a/include/salticidae/util.h
+++ b/include/salticidae/util.h
@@ -77,6 +77,11 @@ std::vector<std::string> trim_all(const std::vector<std::string> &ss);
std::string vstringprintf(const char *fmt, va_list ap);
std::string stringprintf(const char *fmt, ...);
+template<typename SerialType>
+inline std::string get_hex10(const SerialType &x) {
+ return get_hex(x).substr(0, 10);
+}
+
enum SalticidaeErrorCode {
SALTI_NORMAL,
SALTI_ERROR_GENERIC,
diff --git a/src/network.cpp b/src/network.cpp
index 921ea03..286c3ef 100644
--- a/src/network.cpp
+++ b/src/network.cpp
@@ -177,6 +177,27 @@ bool msgnetwork_conn_is_terminated(const msgnetwork_conn_t *conn) {
// PeerNetwork
+void peerid_free(const peerid_t *self) { delete self; }
+peerid_t *peerid_new_from_netaddr(const netaddr_t *addr) {
+ return new peerid_t(*addr);
+}
+
+peerid_t *peerid_new_from_x509(const x509_t *cert) {
+ return new peerid_t(*cert);
+}
+
+peerid_array_t *peerid_array_new() { return new peerid_array_t(); }
+peerid_array_t *peerid_array_new_from_peerids(const peerid_t * const *peers, size_t npeers) {
+ auto res = new peerid_array_t();
+ res->resize(npeers);
+ for (size_t i = 0; i < npeers; i++)
+ (*res)[i] = *peers[i];
+ return res;
+}
+
+void peerid_array_free(peerid_array_t *self) { delete self; }
+
+
peernetwork_config_t *peernetwork_config_new() {
return new peernetwork_config_t();
}
@@ -206,23 +227,23 @@ peernetwork_t *peernetwork_new(const eventcontext_t *ec, const peernetwork_confi
void peernetwork_free(const peernetwork_t *self) { delete self; }
-int32_t peernetwork_add_peer(peernetwork_t *self, const netaddr_t *addr) {
- return self->add_peer(*addr);
+int32_t peernetwork_add_peer(peernetwork_t *self, const peerid_t *pid) {
+ return self->add_peer(*pid);
}
-int32_t peernetwork_del_peer(peernetwork_t *self, const netaddr_t *addr) {
- return self->del_peer(*addr);
+int32_t peernetwork_del_peer(peernetwork_t *self, const peerid_t *pid) {
+ return self->del_peer(*pid);
}
-bool peernetwork_has_peer(const peernetwork_t *self, const netaddr_t *addr) {
- return self->has_peer(*addr);
+bool peernetwork_has_peer(const peernetwork_t *self, const peerid_t *pid) {
+ return self->has_peer(*pid);
}
const peernetwork_conn_t *peernetwork_get_peer_conn(const peernetwork_t *self,
- const netaddr_t *addr,
+ const peerid_t *pid,
SalticidaeCError *cerror) {
SALTICIDAE_CERROR_TRY(cerror)
- return new peernetwork_conn_t(self->get_peer_conn(*addr));
+ return new peernetwork_conn_t(self->get_peer_conn(*pid));
SALTICIDAE_CERROR_CATCH(cerror)
return nullptr;
}
@@ -251,9 +272,9 @@ netaddr_t *peernetwork_conn_get_peer_addr(const peernetwork_conn_t *self) {
void peernetwork_conn_free(const peernetwork_conn_t *self) { delete self; }
-bool peernetwork_send_msg(peernetwork_t *self, const msg_t * msg, const netaddr_t *addr) {
+bool peernetwork_send_msg(peernetwork_t *self, const msg_t * msg, const peerid_t *peer) {
try {
- self->_send_msg(*msg, *addr);
+ self->_send_msg(*msg, *peer);
return true;
} catch (...) {
return false;
@@ -261,13 +282,13 @@ bool peernetwork_send_msg(peernetwork_t *self, const msg_t * msg, const netaddr_
}
int32_t peernetwork_send_msg_deferred_by_move(peernetwork_t *self,
- msg_t *_moved_msg, const netaddr_t *addr) {
- return self->_send_msg_deferred(std::move(*_moved_msg), *addr);
+ msg_t *_moved_msg, const peerid_t *peer) {
+ return self->_send_msg_deferred(std::move(*_moved_msg), *peer);
}
int32_t peernetwork_multicast_msg_by_move(peernetwork_t *self,
- msg_t *_moved_msg, const netaddr_array_t *addrs) {
- return self->_multicast_msg(std::move(*_moved_msg), *addrs);
+ msg_t *_moved_msg, const peerid_array_t *peers) {
+ return self->_multicast_msg(std::move(*_moved_msg), *peers);
}
void peernetwork_listen(peernetwork_t *self, const netaddr_t *listen_addr, SalticidaeCError *cerror) {
diff --git a/test/test_msg.cpp b/test/test_msg.cpp
index ee13166..d21b7f3 100644
--- a/test/test_msg.cpp
+++ b/test/test_msg.cpp
@@ -64,7 +64,7 @@ struct MsgTest {
const opcode_t MsgTest::opcode;
int main() {
- salticidae::MsgBase<opcode_t> msg(MsgTest(10));
+ salticidae::MsgBase<opcode_t> msg(MsgTest(10), 0x0);
printf("%s\n", std::string(msg).c_str());
MsgTest parse(msg.get_payload());
return 0;
diff --git a/test/test_p2p.cpp b/test/test_p2p.cpp
index aff712a..4b6d451 100644
--- a/test/test_p2p.cpp
+++ b/test/test_p2p.cpp
@@ -120,8 +120,25 @@ struct Net {
}
void add_peer(const std::string &listen_addr) {
+ NetAddr addr(listen_addr);
try {
- net->add_peer(NetAddr(listen_addr));
+ net->add_peer(addr);
+ } catch (std::exception &err) {
+ fprintf(stdout, "net %lu: got error during a sync call: %s\n", id, err.what());
+ }
+ }
+
+ void set_peer_addr(const NetAddr &addr) {
+ try {
+ net->set_peer_addr(addr, addr);
+ } catch (std::exception &err) {
+ fprintf(stdout, "net %lu: got error during a sync call: %s\n", id, err.what());
+ }
+ }
+
+ void conn_peer(const NetAddr &addr) {
+ try {
+ net->conn_peer(addr);
} catch (std::exception &err) {
fprintf(stdout, "net %lu: got error during a sync call: %s\n", id, err.what());
}
@@ -249,6 +266,46 @@ int main(int argc, char **argv) {
it->second->del_peer(it2->second->listen_addr);
};
+ auto cmd_setpeeraddr = [](char *buff) {
+ int id = read_int(buff);
+ if (id < 0) return;
+ auto it = nets.find(id);
+ if (it == nets.end())
+ {
+ fprintf(stdout, "net id does not exist\n");
+ return;
+ }
+ int id2 = read_int(buff);
+ if (id2 < 0) return;
+ auto it2 = nets.find(id2);
+ if (it2 == nets.end())
+ {
+ fprintf(stdout, "net id does not exist\n");
+ return;
+ }
+ it->second->set_peer_addr(it2->second->listen_addr);
+ };
+
+ auto cmd_connpeer = [](char *buff) {
+ int id = read_int(buff);
+ if (id < 0) return;
+ auto it = nets.find(id);
+ if (it == nets.end())
+ {
+ fprintf(stdout, "net id does not exist\n");
+ return;
+ }
+ int id2 = read_int(buff);
+ if (id2 < 0) return;
+ auto it2 = nets.find(id2);
+ if (it2 == nets.end())
+ {
+ fprintf(stdout, "net id does not exist\n");
+ return;
+ }
+ it->second->conn_peer(it2->second->listen_addr);
+ };
+
auto cmd_msg = [](char *buff) {
int id = read_int(buff);
if (id < 0) return;
@@ -267,7 +324,7 @@ int main(int argc, char **argv) {
return;
}
scanf("%64s", buff);
- it->second->net->send_msg(MsgText(id, buff), it2->second->listen_addr);
+ it->second->net->send_msg(MsgText(id, buff), NetAddr(it2->second->listen_addr));
};
auto cmd_sleep = [](char *buff) {
@@ -280,6 +337,8 @@ int main(int argc, char **argv) {
fprintf(stdout,
"add <node-id> <port> -- start a node (create a PeerNetwork instance)\n"
"addpeer <node-id> <peer-id> -- add a peer to a given node\n"
+ "setpeeraddr <node-id> <peer-id> -- set the peer addr\n"
+ "connpeer <node-id> <peer-id> -- try to connect to the peer\n"
"delpeer <node-id> <peer-id> -- add a peer to a given node\n"
"del <node-id> -- remove a node (destroy a PeerNetwork instance)\n"
"msg <node-id> <peer-id> <msg> -- send a text message to a node\n"
@@ -292,6 +351,8 @@ int main(int argc, char **argv) {
cmd_map.insert(std::make_pair("add", cmd_add));
cmd_map.insert(std::make_pair("addpeer", cmd_addpeer));
+ cmd_map.insert(std::make_pair("setpeeraddr", cmd_setpeeraddr));
+ cmd_map.insert(std::make_pair("connpeer", cmd_connpeer));
cmd_map.insert(std::make_pair("del", cmd_del));
cmd_map.insert(std::make_pair("delpeer", cmd_delpeer));
cmd_map.insert(std::make_pair("msg", cmd_msg));
diff --git a/test/test_p2p_tls.cpp b/test/test_p2p_tls.cpp
index 93cefac..10dacff 100644
--- a/test/test_p2p_tls.cpp
+++ b/test/test_p2p_tls.cpp
@@ -296,7 +296,7 @@ int main(int argc, char **argv) {
return;
}
scanf("%64s", buff);
- it->second->net->send_msg(MsgText(id, buff), it2->second->listen_addr);
+ it->second->net->send_msg(MsgText(id, buff), NetAddr(it2->second->listen_addr));
};
auto cmd_sleep = [](char *buff) {