#pragma once #include "Destination.h" #include "Type.h" #include #include namespace RNS { class ResourceRequest; class ResourceResponse; class RequestReceipt; class Link; class LinkData; class RequestReceiptData; class Resource; class Packet; class Destination; class ResourceAdvertisement; class PacketReceipt; class ResourceRequest { public: double _requested_at = 0.0; Bytes _path_hash; Bytes _request_data; }; class ResourceResponse { Bytes request_id; Bytes response_data; }; /* An instance of this class is returned by the ``request`` method of ``RNS.Link`` instances. It should never be instantiated manually. It provides methods to check status, response time and response data when the request concludes. */ class RequestReceipt { public: class Callbacks { public: using response = void(*)(const RequestReceipt& packet_receipt); using failed = void(*)(const RequestReceipt& packet_receipt); using progress = void(*)(const RequestReceipt& packet_receipt); public: response _response = nullptr; failed _failed = nullptr; progress _progress = nullptr; friend class RequestReceipt; }; public: RequestReceipt(Type::NoneConstructor none) {} RequestReceipt(const RequestReceipt& request_receipt) : _object(request_receipt._object) {} //RequestReceipt(const Link& link, const PacketReceipt& packet_receipt = {Type::NONE}, const Resource& resource = {Type::NONE}, RequestReceipt::Callbacks::response response_callback = nullptr, RequestReceipt::Callbacks::failed failed_callback = nullptr, RequestReceipt::Callbacks::progress progress_callback = nullptr, double timeout = 0.0, int request_size = 0); RequestReceipt(const Link& link, const PacketReceipt& packet_receipt, const Resource& resource, RequestReceipt::Callbacks::response response_callback = nullptr, RequestReceipt::Callbacks::failed failed_callback = nullptr, RequestReceipt::Callbacks::progress progress_callback = nullptr, double timeout = 0.0, int request_size = 0); inline RequestReceipt& operator = (const RequestReceipt& packet_receipt) { _object = packet_receipt._object; return *this; } inline operator bool() const { return _object.get() != nullptr; } inline bool operator < (const RequestReceipt& packet_receipt) const { return _object.get() < packet_receipt._object.get(); } public: void request_resource_concluded(const Resource& resource); void __response_timeout_job(); void request_timed_out(const PacketReceipt& packet_receipt); void response_resource_progress(const Resource& resource); void response_received(const Bytes& response); const Bytes& get_request_id() const; Type::RequestReceipt::status get_status() const; float get_progress() const; const Bytes get_response() const; double get_response_time() const; std::string toString() const; // getters const Bytes& hash() const; const Bytes& request_id() const; size_t response_transfer_size() const; // setters void response_size(size_t size); void response_transfer_size(size_t size); private: std::shared_ptr _object; }; /* This class is used to establish and manage links to other peers. When a link instance is created, Reticulum will attempt to establish verified and encrypted connectivity with the specified destination. :param destination: A :ref:`RNS.Destination` instance which to establish a link to. :param established_callback: An optional function or method with the signature *callback(link)* to be called when the link has been established. :param closed_callback: An optional function or method with the signature *callback(link)* to be called when the link is closed. */ class Link { public: class Callbacks { public: using established = void(*)(Link& link); using closed = void(*)(Link& link); using packet = void(*)(const Bytes& plaintext, const Packet& packet); using remote_identified = void(*)(const Link& link, const Identity& remote_identity); using resource = void(*)(const ResourceAdvertisement& resource_advertisement); using resource_started = void(*)(const Resource& resource); using resource_concluded = void(*)(const Resource& resource); public: established _established = nullptr; closed _closed = nullptr; packet _packet = nullptr; remote_identified _remote_identified = nullptr; resource _resource = nullptr; resource_started _resource_started = nullptr; resource_concluded _resource_concluded = nullptr; friend class Link; }; public: static uint8_t resource_strategies; static std::set ENABLED_MODES; static RNS::Type::Link::link_mode MODE_DEFAULT; public: Link(Type::NoneConstructor none) { MEM("Link NONE object created"); } Link(const Link& link) : _object(link._object) { MEM("Link object copy created"); } Link(const Destination& destination = {Type::NONE}, Callbacks::established established_callback = nullptr, Callbacks::closed closed_callback = nullptr, const Destination& owner = {Type::NONE}, const Bytes& peer_pub_bytes = {Bytes::NONE}, const Bytes& peer_sig_pub_bytes = {Bytes::NONE}, RNS::Type::Link::link_mode mode = MODE_DEFAULT); //Link(const Destination& destination = {Type::NONE}, Callbacks::established established_callback = nullptr, Callbacks::closed closed_callback = nullptr, const Destination& owner = {Type::NONE}, const Bytes& peer_pub_bytes = {Bytes::NONE}, const Bytes& peer_sig_pub_bytes = {Bytes::NONE}, RNS::Type::Link::link_mode mode = MODE_DEFAULT); virtual ~Link(){ MEM("Link object destroyed"); } Link& operator = (const Link& link) { _object = link._object; return *this; } operator bool() const { return _object.get() != nullptr; } bool operator < (const Link& link) const { return _object.get() < link._object.get(); } public: static Bytes signalling_bytes(uint16_t mtu, RNS::Type::Link::link_mode mode); static uint16_t mtu_from_lr_packet(const Packet& packet); static uint16_t mtu_from_lp_packet(const Packet& packet); static uint8_t mode_byte(RNS::Type::Link::link_mode mode); static RNS::Type::Link::link_mode mode_from_lr_packet(const Packet& packet); static RNS::Type::Link::link_mode mode_from_lp_packet(const Packet& packet); static Bytes link_id_from_lr_packet(const Packet& packet); static Link validate_request( const Destination& owner, const Bytes& data, const Packet& packet); public: void load_peer(const Bytes& peer_pub_bytes, const Bytes& peer_sig_pub_bytes); void set_link_id(const Packet& packet); void handshake(); void prove(); void prove_packet(const Packet& packet); void validate_proof(const Packet& packet); void identify(const Identity& identity); const RequestReceipt request(const Bytes& path, const Bytes& data = {Bytes::NONE}, RequestReceipt::Callbacks::response response_callback = nullptr, RequestReceipt::Callbacks::failed failed_callback = nullptr, RequestReceipt::Callbacks::progress progress_callback = nullptr, double timeout = 0.0); void update_mdu(); void rtt_packet(const Packet& packet); float get_establishment_rate(); uint16_t get_mtu(); uint16_t get_mdu(); float get_expected_rate(); RNS::Type::Link::link_mode get_mode(); const Bytes& get_salt(); const Bytes get_context(); double get_age(); double no_inbound_for(); double no_outbound_for(); double no_data_for(); double inactive_for(); const Identity& get_remote_identity(); void had_outbound(bool is_keepalive = false); void teardown(); void teardown_packet(const Packet& packet); void link_closed(); void start_watchdog(); void __watchdog_job(); void send_keepalive(); void handle_request(const Bytes& request_id, const ResourceRequest& unpacked_request); void handle_response(const Bytes& request_id, const Bytes& response_data, size_t response_size, size_t response_transfer_size); void request_resource_concluded(const Resource& resource); void response_resource_concluded(const Resource& resource); //z const Channel& get_channel(); void receive(const Packet& packet); const Bytes encrypt(const Bytes& plaintext); const Bytes decrypt(const Bytes& ciphertext); const Bytes sign(const Bytes& message); bool validate(const Bytes& signature, const Bytes& message); void set_link_established_callback(Callbacks::established callback); void set_link_closed_callback(Callbacks::closed callback); void set_packet_callback(Callbacks::packet callback); void set_remote_identified_callback(Callbacks::remote_identified callback); void set_resource_callback(Callbacks::resource callback); void set_resource_started_callback(Callbacks::resource_started callback); void set_resource_concluded_callback(Callbacks::resource_concluded callback); void resource_concluded(const Resource& resource); void set_resource_strategy(Type::Link::resource_strategy strategy); void register_outgoing_resource(const Resource& resource); void register_incoming_resource(const Resource& resource); bool has_incoming_resource(const Resource& resource); void cancel_outgoing_resource(const Resource& resource); void cancel_incoming_resource(const Resource& resource); bool ready_for_new_resource(); //void __str__(); std::string toString() const; // getters double rtt() const; const Destination& destination() const; // CBA LINK //const Destination& link_destination() const; const Interface& attached_interface() const; const Bytes& link_id() const; const Bytes& hash() const; uint16_t mtu() const; Type::Link::status status() const; double establishment_timeout() const; uint16_t establishment_cost() const; uint8_t traffic_timeout_factor() const; double request_time() const; double last_inbound() const; std::set& pending_requests() const; Type::Link::teardown_reason teardown_reason() const; bool initiator() const; // setters void destination(const Destination& destination); void attached_interface(const Interface& interface); void establishment_timeout(double timeout); void establishment_cost(uint16_t cost); void request_time(double time); void last_inbound(double time); void last_outbound(double time); void increment_tx(); void increment_txbytes(uint16_t bytes); void status(Type::Link::status status); void mtu(uint16_t mtu); void mode(RNS::Type::Link::link_mode mode); protected: std::shared_ptr _object; }; }