Back to Site
Loading...
Searching...
No Matches
librats::Node Class Referencefinal

#include <node.h>

Inheritance diagram for librats::Node:
[legend]
Collaboration diagram for librats::Node:
[legend]

Public Member Functions

 Node (NodeConfig config)
 Construct a node from its configuration (see NodeConfig).
 
 ~Node () override
 Stops the node if still running, then releases all resources.
 
 Node (const Node &)=delete
 
Nodeoperator= (const Node &)=delete
 
template<class T >
T * add_subsystem (std::unique_ptr< T > subsystem)
 Attach a subsystem (DHT, GossipSub, PingService…).
 
bool start ()
 Bring the node up: open the listener (if enabled), start the reactor pool, then start every attached subsystem.
 
void stop ()
 Tear the node down: stop subsystems (reverse order), close all connections, and join the reactor pool.
 
const PeerIdlocal_id () const noexcept override
 Our self-certifying peer identity (the public key peers authenticate).
 
uint16_t listen_port () const noexcept override
 The bound listen port (the actual port when the config requested 0).
 
uint8_t transports () const noexcept override
 Transports this node is actually running, as a PeerTransports bitmask.
 
const std::string & protocol () const noexcept override
 Application protocol identity bound into the handshake (see NodeConfig).
 
EventBusevents () noexcept
 
ServiceRegistryservices () noexcept
 
void connect (const Address &address) override
 Dial a peer.
 
void connect (const std::string &host, uint16_t port)
 Dial a peer.
 
size_t peer_count () const noexcept
 Number of currently-established peers.
 
std::vector< PeerInfopeers () const override
 Snapshot of all established peers (id, addresses, direction, timing).
 
std::optional< Peerpeer (const PeerId &id)
 Handle to a connected peer by id, or std::nullopt if not connected.
 
std::vector< Addressobserved_addresses () const
 Our own addresses as remote peers reported observing us at — their observed IP paired with our listen port.
 
const NatStatusnat_status () const noexcept
 What the mesh has shown about our own side of the NAT, from the endpoints datagram peers report observing our shared UDP socket at (see nat_status.h).
 
bool dial_direct (const Address &addr, TransportKind kind, const DialProfile &profile) override
 Start exactly one dial to addr over kind, bypassing the transport race.
 
std::optional< PeerRoute > adopt_circuit (const PeerId &carrier, std::unique_ptr< Link > link, ConnRole role, bool connected) override
 Adopt link as a connection carried by the peer carrier, on the reactor that owns the carrier's own connection.
 
void wake_circuit (PeerRoute route, uint32_t events) override
 Deliver poll-equivalent events (PollIn / PollOut / PollErr, see core/io_poller.h) to a circuit connection — the events a socket-backed link would have got from the poller.
 
void close_circuit (PeerRoute route, CloseReason reason) override
 Tear a circuit connection down.
 
size_t max_peers () const noexcept
 
void set_max_peers (size_t n) noexcept
 
bool peer_limit_reached () const noexcept
 
bool send (const PeerId &to, std::string_view channel, ByteView payload)
 Send raw bytes to one peer on a named channel.
 
bool broadcast (std::string_view channel, ByteView payload)
 Send raw bytes on a named channel to every connected peer.
 
bool peer_writable (const PeerId &id) const override
 Whether a peer's send queue has room for more.
 
void on_peer_connected (PeerNetwork::PeerEventHandler cb) override
 Subscribe to peer-connected events. The handler runs on a reactor thread.
 
void on_peer_disconnected (PeerNetwork::PeerDisconnectHandler cb) override
 Subscribe to peer-disconnected events. The handler runs on a reactor thread.
 
void on_dial_failed (PeerNetwork::DialFailedHandler cb) override
 Subscribe to failed-outbound-dial events. The handler runs on a reactor thread.
 
void on_peer_writable (PeerNetwork::PeerEventHandler cb) override
 Subscribe to "this peer can be written to again" — fired when a peer whose send queue had filled past its mark has drained back under it.
 
void on (std::string_view channel, MessageRouter::Handler cb)
 Register a handler for inbound messages on a named channel.
 
template<class T >
T * subsystem () noexcept
 
MessageJsonjson () noexcept
 The JSON messaging module if one was attached (add_subsystem<MessageJson>), else nullptr.
 
bool send (const PeerId &to, MessageType type, ByteView payload) override
 Send to one peer.
 
bool broadcast (MessageType type, ByteView payload) override
 Send to every connected peer.
 
std::vector< PeerIdconnected_peers () const override
 
void on (MessageType type, PeerNetwork::MessageHandler cb) override
 
- Public Member Functions inherited from librats::PeerNetwork
virtual ~PeerNetwork ()=default
 
- Public Member Functions inherited from librats::DialService
virtual ~DialService ()=default
 
- Public Member Functions inherited from librats::CircuitService
virtual ~CircuitService ()=default
 

Friends

class Peer
 

Additional Inherited Members

- Public Types inherited from librats::PeerNetwork
using MessageHandler = std::function< void(const Peer &, ByteView)>
 
using PeerEventHandler = std::function< void(const Peer &)>
 
using PeerDisconnectHandler = std::function< void(const PeerId &, CloseReason)>
 A peer went away, and why.
 
using DialFailedHandler = std::function< void(const Address &)>
 

Detailed Description

Definition at line 78 of file node.h.

Constructor & Destructor Documentation

◆ Node() [1/2]

librats::Node::Node ( NodeConfig  config)
explicit

Construct a node from its configuration (see NodeConfig).

This only loads the identity and prepares the layers; no socket is opened until start().

◆ ~Node()

librats::Node::~Node ( )
override

Stops the node if still running, then releases all resources.

◆ Node() [2/2]

librats::Node::Node ( const Node )
delete

Member Function Documentation

◆ add_subsystem()

template<class T >
T * librats::Node::add_subsystem ( std::unique_ptr< T >  subsystem)
inline

Attach a subsystem (DHT, GossipSub, PingService…).

Call before start(); the node owns it (single ownership), gives it a PeerNetwork on start(), and stops it on stop(). Returns a non-owning pointer to the just-added subsystem so the caller can drive its API without a separate get()/move dance — valid for the node's lifetime: auto* files = node.add_subsystem(std::make_unique<FileTransfer>("./dl"));

Definition at line 99 of file node.h.

◆ adopt_circuit()

std::optional< PeerRoute > librats::Node::adopt_circuit ( const PeerId carrier,
std::unique_ptr< Link >  link,
ConnRole  role,
bool  connected 
)
overridevirtual

Adopt link as a connection carried by the peer carrier, on the reactor that owns the carrier's own connection.

Parameters
roleOutbound for a circuit we opened, Inbound for one opened to us. It is what the secure handshake and the peer table's duplicate resolution read, so it must say who asked.
connectedwhether the far end is already there. An inbound circuit is (the opener would not have sent it otherwise); an outbound one is not until its acceptance arrives, and until then the connection waits in Connecting for a PollOut.
Returns
the new connection's route, or nullopt when the carrier is no longer a peer, or when an inbound circuit would push this node past its peer limit. Nothing is started in that case and link is released.

Implements librats::CircuitService.

◆ broadcast() [1/2]

bool librats::Node::broadcast ( MessageType  type,
ByteView  payload 
)
overridevirtual

Send to every connected peer.

Returns
whether every one of them still has room, so a subsystem that fans out can pause on the slowest.

Implements librats::PeerNetwork.

◆ broadcast() [2/2]

bool librats::Node::broadcast ( std::string_view  channel,
ByteView  payload 
)

Send raw bytes on a named channel to every connected peer.

Returns
whether every one of them still has room — a fan-out can only usefully be paced by its slowest recipient.

Coarser than send(): the answer is the reactors' view as they last left it and does not count what this call has just handed over, because a broadcast is dispatched per reactor rather than per peer. Good enough to pace a periodic fan-out; when precise backpressure matters — a file transfer, a large stream — address peers individually with send().

◆ close_circuit()

void librats::Node::close_circuit ( PeerRoute  route,
CloseReason  reason 
)
overridevirtual

Tear a circuit connection down.

Thread-safe; a no-op for a route that is already gone.

Implements librats::CircuitService.

◆ connect() [1/2]

void librats::Node::connect ( const Address address)
overridevirtual

Dial a peer.

Non-blocking: the connection (transport + handshake) completes asynchronously and surfaces via on_peer_connected. A duplicate or self-connection is detected and dropped after the handshake.

The transport is chosen by the dialer (see node/dialer.h): the preferred one first, the other raced in after NodeConfig::transport_fallback_ms if the first has not come up. Whichever completes its handshake first wins.

Implements librats::PeerNetwork.

◆ connect() [2/2]

void librats::Node::connect ( const std::string &  host,
uint16_t  port 
)

Dial a peer.

Non-blocking: the connection (transport + handshake) completes asynchronously and surfaces via on_peer_connected. A duplicate or self-connection is detected and dropped after the handshake.

The transport is chosen by the dialer (see node/dialer.h): the preferred one first, the other raced in after NodeConfig::transport_fallback_ms if the first has not come up. Whichever completes its handshake first wins.

◆ connected_peers()

std::vector< PeerId > librats::Node::connected_peers ( ) const
overridevirtual

Implements librats::PeerNetwork.

◆ dial_direct()

bool librats::Node::dial_direct ( const Address addr,
TransportKind  kind,
const DialProfile &  profile 
)
overridevirtual

Start exactly one dial to addr over kind, bypassing the transport race.

Non-blocking; the outcome surfaces through the node's ordinary peer-connected event. Returns false when the node cannot carry that transport at all (no datagram socket, or an address family the one socket cannot reach), in which case nothing was started and no failure event will follow.

Implements librats::DialService.

◆ events()

EventBus & librats::Node::events ( )
inlinenoexcept

Definition at line 132 of file node.h.

◆ json()

MessageJson * librats::Node::json ( )
noexcept

The JSON messaging module if one was attached (add_subsystem<MessageJson>), else nullptr.

Convenience over subsystem<MessageJson>(); defined in node.cpp.

◆ listen_port()

uint16_t librats::Node::listen_port ( ) const
inlineoverridevirtualnoexcept

The bound listen port (the actual port when the config requested 0).

Both transports share it, so one advertised address is dialable over either.

Implements librats::PeerNetwork.

Definition at line 119 of file node.h.

◆ local_id()

const PeerId & librats::Node::local_id ( ) const
inlineoverridevirtualnoexcept

Our self-certifying peer identity (the public key peers authenticate).

Implements librats::PeerNetwork.

Definition at line 116 of file node.h.

◆ max_peers()

size_t librats::Node::max_peers ( ) const
inlinenoexcept

Definition at line 178 of file node.h.

◆ nat_status()

const NatStatus & librats::Node::nat_status ( ) const
inlinenoexcept

What the mesh has shown about our own side of the NAT, from the endpoints datagram peers report observing our shared UDP socket at (see nat_status.h).

Also published in services() as ExternalAddressService, which is how a NAT-traversal subsystem reaches it.

Definition at line 163 of file node.h.

◆ observed_addresses()

std::vector< Address > librats::Node::observed_addresses ( ) const

Our own addresses as remote peers reported observing us at — their observed IP paired with our listen port.

De-duplicated and bounded; populated as peers send their identify message. Useful for NAT awareness / advertising.

◆ on() [1/2]

void librats::Node::on ( MessageType  type,
PeerNetwork::MessageHandler  cb 
)
inlineoverridevirtual

Implements librats::PeerNetwork.

Definition at line 268 of file node.h.

◆ on() [2/2]

void librats::Node::on ( std::string_view  channel,
MessageRouter::Handler  cb 
)
inline

Register a handler for inbound messages on a named channel.

Additive: multiple handlers may coexist. The handler runs on a reactor thread.

Definition at line 250 of file node.h.

◆ on_dial_failed()

void librats::Node::on_dial_failed ( PeerNetwork::DialFailedHandler  cb)
inlineoverridevirtual

Subscribe to failed-outbound-dial events. The handler runs on a reactor thread.

Implements librats::PeerNetwork.

Definition at line 242 of file node.h.

◆ on_peer_connected()

void librats::Node::on_peer_connected ( PeerNetwork::PeerEventHandler  cb)
inlineoverridevirtual

Subscribe to peer-connected events. The handler runs on a reactor thread.

Implements librats::PeerNetwork.

Definition at line 238 of file node.h.

◆ on_peer_disconnected()

void librats::Node::on_peer_disconnected ( PeerNetwork::PeerDisconnectHandler  cb)
inlineoverridevirtual

Subscribe to peer-disconnected events. The handler runs on a reactor thread.

Implements librats::PeerNetwork.

Definition at line 240 of file node.h.

◆ on_peer_writable()

void librats::Node::on_peer_writable ( PeerNetwork::PeerEventHandler  cb)
inlineoverridevirtual

Subscribe to "this peer can be written to again" — fired when a peer whose send queue had filled past its mark has drained back under it.

The other half of send() returning false; an application that never checks that return never needs this. The handler runs on a reactor thread.

Reimplemented from librats::PeerNetwork.

Definition at line 247 of file node.h.

◆ operator=()

Node & librats::Node::operator= ( const Node )
delete

◆ peer()

std::optional< Peer > librats::Node::peer ( const PeerId id)

Handle to a connected peer by id, or std::nullopt if not connected.

◆ peer_count()

size_t librats::Node::peer_count ( ) const
inlinenoexcept

Number of currently-established peers.

Definition at line 148 of file node.h.

◆ peer_limit_reached()

bool librats::Node::peer_limit_reached ( ) const
inlinenoexcept

Definition at line 180 of file node.h.

◆ peer_writable()

bool librats::Node::peer_writable ( const PeerId id) const
overridevirtual

Whether a peer's send queue has room for more.

False for a peer that is not connected.

The same question send() answers, asked without sending anything: it weighs both halves of what the peer is carrying — the bytes the reactor has queued, and the bytes a caller has handed to send() that the reactor has not taken up yet. So it is safe to poll: a caller that has just filled the queue in a tight loop keeps being told "no room" until the reactor has actually looked at what it was given, rather than being told "go on" because nothing observable has changed yet.

It stays a hint about a queue that drains as it is read, so the ordinary flow is unchanged: the signal to stop is the return of send(), and the signal to resume is on_peer_writable. This is for a caller that must wait for room on a thread of its own — the event alone cannot serve it, because a queue that filled only with bytes still in transit never crossed anything on the connection and so raises no event when they drain.

Reimplemented from librats::PeerNetwork.

◆ peers()

std::vector< PeerInfo > librats::Node::peers ( ) const
inlineoverridevirtual

Snapshot of all established peers (id, addresses, direction, timing).

Implements librats::PeerNetwork.

Definition at line 150 of file node.h.

◆ protocol()

const std::string & librats::Node::protocol ( ) const
inlineoverridevirtualnoexcept

Application protocol identity bound into the handshake (see NodeConfig).

Implements librats::PeerNetwork.

Definition at line 127 of file node.h.

◆ send() [1/2]

bool librats::Node::send ( const PeerId to,
MessageType  type,
ByteView  payload 
)
overridevirtual

Send to one peer.

Returns
whether that peer's send queue still has room; false means "stop and wait for on_peer_writable" — the message is queued either way, but continuing past this is what gets a peer dropped as a slow consumer. Also false if the peer is not connected. Wait on the event and not on a poll of the queue's state: the answer is re-derived on the reactor thread, so a caller that spins instead of yielding never lets it change.

Implements librats::PeerNetwork.

◆ send() [2/2]

bool librats::Node::send ( const PeerId to,
std::string_view  channel,
ByteView  payload 
)

Send raw bytes to one peer on a named channel.

Non-blocking; the payload is copied into the peer's send queue. No-op if the peer is not connected.

Parameters
todestination peer id
channelapplication channel name (interned to a 16-bit id)
payloadmessage bytes (copied)
Returns
whether that peer's queue still has room. False means stop: this message is queued like any other, but the queue is past its low-water mark, and an application that keeps going regardless will eventually have the peer dropped as a slow consumer. Wait for on_peer_writable instead. Also false if the peer is not connected.

"Stop" is meant literally, and yielding is part of it: the mark is re-tested inside the reactor task this call hands off to, and it is that test which flips the peer to unwritable and later raises on_peer_writable. A caller that answers a false by looping straight back into send() therefore starves the very thread that would tell it to stop — the queue keeps growing while the signal it is waiting for never gets a turn to be produced.

◆ services()

ServiceRegistry & librats::Node::services ( )
inlinenoexcept

Definition at line 133 of file node.h.

◆ set_max_peers()

void librats::Node::set_max_peers ( size_t  n)
inlinenoexcept

Definition at line 179 of file node.h.

◆ start()

bool librats::Node::start ( )

Bring the node up: open the listener (if enabled), start the reactor pool, then start every attached subsystem.

Register callbacks and attach subsystems BEFORE calling this.

Returns
true on success; false if the listener could not bind.

◆ stop()

void librats::Node::stop ( )

Tear the node down: stop subsystems (reverse order), close all connections, and join the reactor pool.

Safe to call once; idempotent.

◆ subsystem()

template<class T >
T * librats::Node::subsystem ( )
inlinenoexcept

Definition at line 256 of file node.h.

◆ transports()

uint8_t librats::Node::transports ( ) const
inlineoverridevirtualnoexcept

Transports this node is actually running, as a PeerTransports bitmask.

May be narrower than the config asked for — a UDP socket that could not be bound leaves the node TCP-only rather than failing to start.

Reimplemented from librats::PeerNetwork.

Definition at line 124 of file node.h.

◆ wake_circuit()

void librats::Node::wake_circuit ( PeerRoute  route,
uint32_t  events 
)
overridevirtual

Deliver poll-equivalent events (PollIn / PollOut / PollErr, see core/io_poller.h) to a circuit connection — the events a socket-backed link would have got from the poller.

Thread-safe, and a no-op for a route that is already gone.

Implements librats::CircuitService.

Friends And Related Symbol Documentation

◆ Peer

friend class Peer
friend

Definition at line 271 of file node.h.


The documentation for this class was generated from the following file: