-
Notifications
You must be signed in to change notification settings - Fork 1
C API
Name | |
---|---|
struct |
p2p::PeerID Alias equating a PeerID and a string. |
class |
p2p::Key Represents a P2P cryptographic private key. |
struct |
p2p::Topic Represents a P2P topic. |
class |
p2p::Network Represents the P2P network. |
struct |
p2p::Message Represents a P2P message. |
Name | |
---|---|
constexpr bool |
do_not_initialize Constant to indicate that initialization should not be performed automatically. |
constexpr std::string_view |
default_listen_address Default listen address used for network initialization. |
constexpr std::string_view |
default_discovery_topic Default discovery topic used for network initialization. |
constexpr bool do_not_initialize = false;
Constant to indicate that initialization should not be performed automatically.
constexpr std::string_view default_listen_address = "/ip4/0.0.0.0/udp/0/quic-v1";
Default listen address used for network initialization.
constexpr std::string_view default_discovery_topic = "simpleP2P";
Default discovery topic used for network initialization.
Alias equating a PeerID and a string.
Inherits from std::string
Name | |
---|---|
using std::string_view | view |
Name | |
---|---|
PeerID(const std::string & o) | |
PeerID(std::string && o) | |
PeerID(const PeerID & ) =default | |
PeerID(PeerID && ) =default | |
PeerID & | operator=(const PeerID & ) =default |
PeerID & | operator=(PeerID && ) =default |
using p2p::PeerID::view = std::string_view;
inline PeerID(
const std::string & o
)
inline PeerID(
std::string && o
)
PeerID(
const PeerID &
) =default
PeerID(
PeerID &&
) =default
PeerID & operator=(
const PeerID &
) =default
PeerID & operator=(
PeerID &&
) =default
Represents a P2P cryptographic private key.
Name | |
---|---|
Key() =default Default constructor. |
|
Key(P2PKey && o) Move constructor. |
|
Key(const Key & ) =default Copy constructor. |
|
Key(Key && ) =default Move constructor. |
|
Key & |
operator=(P2PKey && o) Move assignment operator. |
Key & |
operator=(const Key & ) =default Copy assignment operator. |
Key & |
operator=(Key && ) =default Move assignment operator. |
operator P2PKey() Conversion operator to P2PKey. |
|
operator P2PKey() const Conversion operator to P2PKey (const version). |
|
std::ostream & |
save(std::ostream & out) const Saves the Key object to an output stream. |
std::istream & |
load(std::istream & in) Loads the Key object from an input stream. |
Key |
generate() Generates a new P2P key. |
Key() =default
Default constructor.
inline Key(
P2PKey && o
)
Move constructor.
Parameters:
- o The Key object to move from.
Key(
const Key &
) =default
Copy constructor.
Parameters:
- o The Key object to copy from.
Key(
Key &&
) =default
Move constructor.
Parameters:
- o The Key object to move from.
inline Key & operator=(
P2PKey && o
)
Move assignment operator.
Parameters:
- o The Key object to move from.
Return: Reference to the assigned Key object.
Key & operator=(
const Key &
) =default
Copy assignment operator.
Parameters:
- o The Key object to copy from.
Return: Reference to the assigned Key object.
Key & operator=(
Key &&
) =default
Move assignment operator.
Parameters:
- o The Key object to move from.
Return: Reference to the assigned Key object.
inline operator P2PKey()
Conversion operator to P2PKey.
Return: The underlying P2PKey structure.
inline operator P2PKey() const
Conversion operator to P2PKey (const version).
Return: The underlying P2PKey structure.
inline std::ostream & save(
std::ostream & out
) const
Saves the Key object to an output stream.
Parameters:
- out The output stream to save to.
Return: Reference to the output stream.
inline std::istream & load(
std::istream & in
)
Loads the Key object from an input stream.
Parameters:
- in The input stream to load from.
Return: Reference to the input stream.
static inline Key generate()
Generates a new P2P key.
Return: The generated Key object.
Represents a P2P topic.
Name | |
---|---|
Topic |
find(std::string_view name) Finds a topic by name. |
bool |
valid() const Checks if the Topic object is valid. |
operator bool() const | |
std::string |
name() const Gets the name of the topic. |
bool |
leave() Leaves the topic. |
Name | |
---|---|
P2PTopic | id |
static inline Topic find(
std::string_view name
)
Finds a topic by name.
Parameters:
- name The name of the topic to find.
Return: The Topic object representing the found topic.
inline bool valid() const
Checks if the Topic object is valid.
Return: True if the topic is valid, false otherwise.
inline operator bool() const
inline std::string name() const
Gets the name of the topic.
Return: The name of the topic.
inline bool leave()
Leaves the topic.
Return: True if successfully left the topic, false otherwise.
P2PTopic id;
Represents the P2P network.
Name | |
---|---|
Network & |
get_singleton() Gets the singleton instance of the Network class. |
Network(std::string_view listenAddress =default_listen_address, std::string_view discoveryTopic =default_discovery_topic, const Key & identityKey ={}, delegate_function< void()> do_on_connected =nullptr, std::chrono::milliseconds connectionTimeout =std::chrono::seconds(60), bool verbose =false) =default Constructor that initializes the P2P network connection. |
|
Network(bool dontInit) Constructor for not automatically initializing the network. |
|
~Network() Destructor. |
|
Network(const Network & ) =delete Copy constructor (deleted). |
|
Network(Network && ) =delete Move constructor (deleted). |
|
void |
initialize(std::string_view listenAddress =default_listen_address, std::string_view discoveryTopic =default_discovery_topic, const Key & identityKey ={}, std::chrono::milliseconds connectionTimeout =std::chrono::seconds(60), bool verbose =false) =default Initializes the P2P network connection. |
void |
shutdown() Shuts down the network connection. |
PeerID |
local_id() const Gets the local hashed ID for the P2P network. |
Topic |
subscribe_to_topic(std::string_view name) Subscribes to a topic with the provided name. |
bool |
broadcast_message(std::string_view message, Topic topic) const Broadcasts a message to a topic. |
bool |
broadcast_message(std::string_view message) const Broadcasts a message to the default topic. |
bool |
broadcast_message(std::span< std::byte > message, Topic topic) const Broadcasts a byte-span message to a topic. |
bool |
broadcast_message(std::span< std::byte > message) const Broadcasts a byte-span message to the default topic. |
Name | |
---|---|
Topic |
defaultTopic the default topic that the network originally joined |
delegate< void(struct Message &)> | on_message |
delegate< void(PeerID::view)> | on_peer_connected |
delegate< void(PeerID::view)> | on_peer_disconnected |
delegate< void(Topic)> | on_topic_subscribed |
delegate< void(Topic)> | on_topic_unsubscribed |
delegate< void()> | on_connected |
delegate< void()> | on_disconnected |
Name | |
---|---|
void |
override_message_callback(P2PMsgCallback callback) Overrides the message callback with the provided function pointer. |
void |
override_peer_connected_callback(P2PPeerCallback callback) Overrides the peer connected callback with the provided function pointer. |
void |
override_peer_disconnected_callback(P2PPeerCallback callback) Overrides the peer disconnected callback with the provided function pointer. |
void |
override_topic_subscribed_callback(P2PTopicCallback callback) Overrides the topic subscribed callback with the provided function pointer. |
void |
override_topic_unsubscribed_callback(P2PTopicCallback callback) Overrides the topic unsubscribed callback with the provided function pointer. |
void |
override_connected_callback(P2PVoidCallback callback) Overrides the connected callback with the provided function pointer. |
void |
override_disconnected_callback(P2PVoidCallback callback) Overrides the disconnected callback with the provided function pointer. |
static inline Network & get_singleton()
Gets the singleton instance of the Network class.
Return: The singleton instance.
inline Network(
std::string_view listenAddress =default_listen_address,
std::string_view discoveryTopic =default_discovery_topic,
const Key & identityKey ={},
delegate_function< void()> do_on_connected =nullptr,
std::chrono::milliseconds connectionTimeout =std::chrono::seconds(60),
bool verbose =false
) =default
Constructor that initializes the P2P network connection.
Parameters:
- listenAddress The multiaddress we should listen for connections on.
- discoveryTopic The discovery topic for network initialization.
- identityKey The identity key for network initialization.
- do_on_connected Callback function to register in on_connected before initializing the connection
- connectionTimeout The time to wait for a connection before giving up.
- verbose Flag indicating if the GO library should spew some more verbose messages.
inline Network(
bool dontInit
)
Constructor for not automatically initializing the network.
Parameters:
- dontInit Placeholder argument to differentiate from the other constructor.
inline ~Network()
Destructor.
Network(
const Network &
) =delete
Copy constructor (deleted).
Network(
Network &&
) =delete
Move constructor (deleted).
inline void initialize(
std::string_view listenAddress =default_listen_address,
std::string_view discoveryTopic =default_discovery_topic,
const Key & identityKey ={},
std::chrono::milliseconds connectionTimeout =std::chrono::seconds(60),
bool verbose =false
) =default
Initializes the P2P network connection.
Parameters:
- listenAddress The multiaddress we should listen for connections on.
- discoveryTopic The discovery topic for network initialization.
- identityKey The identity key for network initialization.
- connectionTimeout The time to wait for a connection before giving up.
- verbose Flag indicating if the GO library should spew some more verbose messages.
inline void shutdown()
Shuts down the network connection.
inline PeerID local_id() const
Gets the local hashed ID for the P2P network.
Return: The local hashed ID.
inline Topic subscribe_to_topic(
std::string_view name
)
Subscribes to a topic with the provided name.
Parameters:
- name The name of the topic to subscribe to.
Return: The Topic object representing the subscribed topic.
inline bool broadcast_message(
std::string_view message,
Topic topic
) const
Broadcasts a message to a topic.
Parameters:
- message The message to broadcast.
- topic The Topic object representing the target topic.
Return: True if the message was successfully broadcasted, false otherwise.
inline bool broadcast_message(
std::string_view message
) const
Broadcasts a message to the default topic.
Parameters:
- message The message to broadcast.
Return: True if the message was successfully broadcasted, false otherwise.
inline bool broadcast_message(
std::span< std::byte > message,
Topic topic
) const
Broadcasts a byte-span message to a topic.
Parameters:
- message The byte-span message to broadcast.
- topic The Topic object representing the target topic.
Return: True if the message was successfully broadcasted, false otherwise.
inline bool broadcast_message(
std::span< std::byte > message
) const
Broadcasts a byte-span message to the default topic.
Parameters:
- message The byte-span message to broadcast.
Return: True if the message was successfully broadcasted, false otherwise.
Topic defaultTopic;
the default topic that the network originally joined
delegate< void(struct Message &)> on_message;
delegate< void(PeerID::view)> on_peer_connected;
delegate< void(PeerID::view)> on_peer_disconnected;
delegate< void(Topic)> on_topic_subscribed;
delegate< void(Topic)> on_topic_unsubscribed;
delegate< void()> on_connected;
delegate< void()> on_disconnected;
inline void override_message_callback(
P2PMsgCallback callback
)
Overrides the message callback with the provided function pointer.
Parameters:
- callback The function pointer to the message callback.
inline void override_peer_connected_callback(
P2PPeerCallback callback
)
Overrides the peer connected callback with the provided function pointer.
Parameters:
- callback The function pointer to the peer connected callback.
inline void override_peer_disconnected_callback(
P2PPeerCallback callback
)
Overrides the peer disconnected callback with the provided function pointer.
Parameters:
- callback The function pointer to the peer disconnected callback.
inline void override_topic_subscribed_callback(
P2PTopicCallback callback
)
Overrides the topic subscribed callback with the provided function pointer.
Parameters:
- callback The function pointer to the topic subscribed callback.
inline void override_topic_unsubscribed_callback(
P2PTopicCallback callback
)
Overrides the topic unsubscribed callback with the provided function pointer.
Parameters:
- callback The function pointer to the topic unsubscribed callback.
inline void override_connected_callback(
P2PVoidCallback callback
)
Overrides the connected callback with the provided function pointer.
Parameters:
- callback The function pointer to the connected callback.
inline void override_disconnected_callback(
P2PVoidCallback callback
)
Overrides the disconnected callback with the provided function pointer.
Parameters:
- callback The function pointer to the disconnected callback.
Represents a P2P message.
Inherits from P2PMessage
Name | |
---|---|
PeerID::view |
sender() Gets the sender of the message. |
std::string_view |
data_string() Gets the message data as a string view. |
std::span< std::byte > |
data() Gets the message data as a byte span. |
bool |
is_local() Checks if the message was sent by the local node. |
Public Attributes inherited from P2PMessage
Name | |
---|---|
char * |
from ??? |
char * |
seqno The sequence number of the message. |
char * |
topic The topic of the message. |
char * |
signature ??? |
char * |
key The key of the message. |
char * |
id The ID of the message. |
char * |
received_from The sender of the message. |
inline PeerID::view sender()
Gets the sender of the message.
Return: The sender's ID.
inline std::string_view data_string()
Gets the message data as a string view.
Return: The message data as a string view.
inline std::span< std::byte > data()
Gets the message data as a byte span.
Return: The message data as a byte span.
inline bool is_local()
Checks if the message was sent by the local node.
Return: True if the message was sent by the local node, false otherwise.
#ifndef SIMPLE_P2P_NETWORKING_HPP
#define SIMPLE_P2P_NETWORKING_HPP
#include "delegate.hpp"
#include <string_view>
#include <span>
#include <iostream>
#include <vector>
#include <optional>
#include <chrono>
namespace p2p {
#include "simplep2p.h"
struct PeerID: public std::string {
using std::string::string;
using std::string::operator=;
PeerID(const std::string& o) : std::string(o) {}
PeerID(std::string&& o) : std::string(std::move(o)) {}
PeerID(const PeerID&) = default;
PeerID(PeerID&&) = default;
PeerID& operator=(const PeerID&) = default;
PeerID& operator=(PeerID&&) = default;
using view = std::string_view;
};
constexpr bool do_not_initialize = false;
constexpr std::string_view default_listen_address = "/ip4/0.0.0.0/udp/0/quic-v1";
constexpr std::string_view default_discovery_topic = "simpleP2P";
class Key {
std::vector<std::byte> data;
static void freeBase(P2PKey& base) { free((void*)base.data); base.data = nullptr; base.size = 0; }
public:
Key() = default;
Key(P2PKey&& o) : data((std::byte*)o.data, ((std::byte*)o.data) + o.size) { freeBase(o); }
Key(const Key&) = default;
Key(Key&&) = default;
Key& operator=(P2PKey&& o) { data = std::vector<std::byte>((std::byte*)o.data, ((std::byte*)o.data) + o.size); freeBase(o); return *this; }
Key& operator=(const Key&) = default;
Key& operator=(Key&&) = default;
operator P2PKey() { return {(char*)data.data(), (int)data.size()}; }
operator P2PKey() const { return {(char*)data.data(), (int)data.size()}; }
std::ostream& save(std::ostream& out) const {
auto size = data.size();
out.write(reinterpret_cast<char*>(&size), sizeof(size));
out.write((char*)(data.data()), size);
return out;
}
std::istream& load(std::istream& in) {
auto size = data.size();
in.read(reinterpret_cast<char*>(&size), sizeof(size));
data.resize(size);
in.read(reinterpret_cast<char*>(data.data()), size);
return in;
}
static Key generate() { return p2p_generate_key(); }
};
struct Topic {
P2PTopic id;
static Topic find(std::string_view name) { return { p2p_find_topicn(name.data(), name.size()) }; }
bool valid() const { return id >= 0; }
operator bool() const { return valid(); }
std::string name() const {
auto raw = p2p_topic_name(id);
std::string out = raw;
free((char*)raw);
return out;
}
bool leave() { return p2p_leave_topic(id); }
};
class Network {
static Network* singleton;
public:
static Network& get_singleton() { return *singleton; }
Topic defaultTopic;
// Multicast delegates representing the different network events
delegate<void(struct Message&)> on_message;
delegate<void(PeerID::view)> on_peer_connected; // Note: only called for directly connected peers... if you need all peers work at a higher level!
delegate<void(PeerID::view)> on_peer_disconnected;
delegate<void(Topic)> on_topic_subscribed;
delegate<void(Topic)> on_topic_unsubscribed;
delegate<void()> on_connected;
delegate<void()> on_disconnected;
Network(
std::string_view listenAddress = default_listen_address,
std::string_view discoveryTopic = default_discovery_topic,
const Key& identityKey = {},
delegate_function<void()> do_on_connected = nullptr,
std::chrono::milliseconds connectionTimeout = std::chrono::seconds(60),
bool verbose = false
) {
singleton = this;
if(do_on_connected != nullptr)
on_connected = do_on_connected;
initialize(listenAddress, discoveryTopic, identityKey, connectionTimeout, verbose);
}
Network(bool dontInit) { singleton = this; }
~Network() { shutdown(); }
Network(const Network&) = delete;
Network(Network&&) = delete;
void initialize(
std::string_view listenAddress = default_listen_address,
std::string_view discoveryTopic = default_discovery_topic,
const Key& identityKey = {},
std::chrono::milliseconds connectionTimeout = std::chrono::seconds(60),
bool verbose = false
) {
// Connect the delegates to the callbacks
override_message_callback(on_mesage_impl);
override_connected_callback(on_connected_impl);
override_disconnected_callback(on_disconnected_impl);
override_peer_connected_callback(on_peer_connected_impl);
override_peer_disconnected_callback(on_peer_disconnected_impl);
override_topic_subscribed_callback(on_topic_subscribed_impl);
override_topic_unsubscribed_callback(on_topic_unsubscribed_impl);
// Initialize the GO library!
defaultTopic = { p2p_initialize({
.listenAddress = listenAddress.data(),
.listenAddressSize = (long long)listenAddress.size(),
.discoveryTopic = discoveryTopic.data(),
.discoveryTopicSize = (long long)discoveryTopic.size(),
.identity = identityKey,
.connectionTimeout = std::chrono::duration_cast<std::chrono::duration<double>>(connectionTimeout).count(),
.verbose = verbose
})};
}
void shutdown() { p2p_shutdown(); }
PeerID local_id() const {
auto raw = p2p_local_id();
std::string out = raw;
free((char*)raw);
return out;
}
Topic subscribe_to_topic(std::string_view name) { return { p2p_subscribe_to_topicn(name.data(), name.size()) }; }
bool broadcast_message(std::string_view message, Topic topic) const { return p2p_broadcast_messagen(message.data(), message.size(), topic.id); }
bool broadcast_message(std::string_view message) const { return broadcast_message(message, defaultTopic); }
bool broadcast_message(std::span<std::byte> message, Topic topic) const { return p2p_broadcast_messagen((char*)message.data(), message.size(), topic.id); }
bool broadcast_message(std::span<std::byte> message) const { return broadcast_message(message, defaultTopic); }
protected:
void override_message_callback(P2PMsgCallback callback) { p2p_set_message_callback(callback); }
void override_peer_connected_callback(P2PPeerCallback callback) { p2p_set_peer_connected_callback(callback); }
void override_peer_disconnected_callback(P2PPeerCallback callback) { p2p_set_peer_disconnected_callback(callback); }
void override_topic_subscribed_callback(P2PTopicCallback callback) { p2p_set_topic_subscribed_callback(callback); }
void override_topic_unsubscribed_callback(P2PTopicCallback callback) { p2p_set_topic_unsubscribed_callback(callback); }
void override_connected_callback(P2PVoidCallback callback) { p2p_set_connected_callback(callback); }
void override_disconnected_callback(P2PVoidCallback callback) { p2p_set_disconnected_callback(callback); }
private:
static bool on_mesage_impl(P2PMessage* msg) {
if(!get_singleton().on_message.empty())
get_singleton().on_message(*reinterpret_cast<struct Message*>(msg));
return true; // Go should never panic!
}
static bool on_peer_connected_impl(char* peerID) {
if(!get_singleton().on_peer_connected.empty())
get_singleton().on_peer_connected(peerID);
return true; // Go should never panic!
}
static bool on_peer_disconnected_impl(char* peerID) {
if(!get_singleton().on_peer_disconnected.empty())
get_singleton().on_peer_disconnected(peerID);
return true; // Go should never panic!
}
static bool on_topic_subscribed_impl(P2PTopic topicID) {
if(!get_singleton().on_topic_subscribed.empty())
get_singleton().on_topic_subscribed({topicID});
return true; // Go should never panic!
}
static bool on_topic_unsubscribed_impl(P2PTopic topicID) {
if(!get_singleton().on_topic_unsubscribed.empty())
get_singleton().on_topic_unsubscribed({topicID});
return true; // Go should never panic!
}
static bool on_connected_impl() {
if(!get_singleton().on_connected.empty())
get_singleton().on_connected();
return true; // Go should never panic!
}
static bool on_disconnected_impl() {
if(!get_singleton().on_disconnected.empty())
get_singleton().on_disconnected();
return true; // Go should never panic!
}
};
#ifdef SIMPLE_P2P_IMPLEMENTATION
Network* Network::singleton = nullptr;
#endif
struct Message: private P2PMessage {
PeerID::view sender() { return received_from; }
std::string_view data_string() { return P2PMessage::data; }
std::span<std::byte> data() { auto view = data_string(); return { (std::byte*)view.data(), view.size() }; }
bool is_local() { return Network::get_singleton().local_id() == sender(); }
};
}
#endif // SIMPLE_P2P_NETWORKING_HPP