mirror of
https://github.com/markqvist/reticulum-cpp.git
synced 2024-10-01 02:55:46 -04:00
WIP: Collection optimizations and Transport
Tested and optimized collections used in Transport. Additional Transport implementation.
This commit is contained in:
parent
263f589801
commit
8d943318a6
@ -26,6 +26,22 @@ lib_deps =
|
|||||||
rweather/Crypto@^0.4.0
|
rweather/Crypto@^0.4.0
|
||||||
lib_compat_mode = off
|
lib_compat_mode = off
|
||||||
|
|
||||||
|
[env:native17]
|
||||||
|
platform = native
|
||||||
|
build_unflags = -std=gnu++11
|
||||||
|
build_flags =
|
||||||
|
-std=c++17
|
||||||
|
-Wall
|
||||||
|
-Wextra
|
||||||
|
-Wno-missing-field-initializers
|
||||||
|
-Wno-format
|
||||||
|
-Wno-unused-parameter
|
||||||
|
-Isrc
|
||||||
|
-DNATIVE
|
||||||
|
lib_deps =
|
||||||
|
rweather/Crypto@^0.4.0
|
||||||
|
lib_compat_mode = off
|
||||||
|
|
||||||
[env:ttgo-t-beam]
|
[env:ttgo-t-beam]
|
||||||
platform = espressif32
|
platform = espressif32
|
||||||
board = ttgo-t-beam
|
board = ttgo-t-beam
|
||||||
|
@ -240,7 +240,7 @@ namespace RNS {
|
|||||||
inline Bytes bytesFromChunk(const uint8_t *ptr, size_t len) { return {ptr, len}; }
|
inline Bytes bytesFromChunk(const uint8_t *ptr, size_t len) { return {ptr, len}; }
|
||||||
//inline Bytes bytesFromString(const char *str) { return Bytes((uint8_t*)str, strlen(str)); }
|
//inline Bytes bytesFromString(const char *str) { return Bytes((uint8_t*)str, strlen(str)); }
|
||||||
inline Bytes bytesFromString(const char *str) { return {(uint8_t*)str, strlen(str)}; }
|
inline Bytes bytesFromString(const char *str) { return {(uint8_t*)str, strlen(str)}; }
|
||||||
//zinline Bytes bytesFromInt(const int) { return {(uint8_t*)str, strlen(str)}; }
|
//z inline Bytes bytesFromInt(const int) { return {(uint8_t*)str, strlen(str)}; }
|
||||||
|
|
||||||
inline std::string stringFromBytes(const Bytes& bytes) { return bytes.toString(); }
|
inline std::string stringFromBytes(const Bytes& bytes) { return bytes.toString(); }
|
||||||
inline std::string hexFromBytes(const Bytes& bytes) { return bytes.toHex(); }
|
inline std::string hexFromBytes(const Bytes& bytes) { return bytes.toHex(); }
|
||||||
|
@ -85,7 +85,7 @@ namespace RNS { namespace Cryptography {
|
|||||||
}
|
}
|
||||||
|
|
||||||
inline const Bytes sign(const Bytes& message) {
|
inline const Bytes sign(const Bytes& message) {
|
||||||
//zreturn _sk.sign(message);
|
//z return _sk.sign(message);
|
||||||
Bytes signature;
|
Bytes signature;
|
||||||
Ed25519::sign(signature.writable(64), _privateKey.data(), _publicKey.data(), message.data(), message.size());
|
Ed25519::sign(signature.writable(64), _privateKey.data(), _publicKey.data(), message.data(), message.size());
|
||||||
return signature;
|
return signature;
|
||||||
|
@ -59,7 +59,7 @@ namespace RNS { namespace Cryptography {
|
|||||||
const float MAX_EXEC_TIME = 500; // in milliseconds
|
const float MAX_EXEC_TIME = 500; // in milliseconds
|
||||||
const uint8_t DELAY_WINDOW = 10;
|
const uint8_t DELAY_WINDOW = 10;
|
||||||
|
|
||||||
//zT_CLEAR = None
|
//z T_CLEAR = None
|
||||||
const uint8_t T_MAX = 0;
|
const uint8_t T_MAX = 0;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
@ -74,6 +74,26 @@ Destination::Destination(const Identity& identity, const directions direction, c
|
|||||||
return Identity::truncated_hash(addr_hash_material);
|
return Identity::truncated_hash(addr_hash_material);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
:returns: A tuple containing the app name and a list of aspects, for a full-name string.
|
||||||
|
*/
|
||||||
|
/*static*/ Bytes Destination::app_and_aspects_from_name(const char* full_name) {
|
||||||
|
//z components = full_name.split(".")
|
||||||
|
//z return (components[0], components[1:])
|
||||||
|
// MOCK
|
||||||
|
return {Bytes::NONE};
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
:returns: A destination name in adressable hash form, for a full name string and Identity instance.
|
||||||
|
*/
|
||||||
|
/*static*/ Bytes Destination::hash_from_name_and_identity(const char* full_name, const Identity& identity) {
|
||||||
|
//z app_name, aspects = Destination.app_and_aspects_from_name(full_name)
|
||||||
|
//z return Destination.hash(identity, app_name, *aspects)
|
||||||
|
// MOCK
|
||||||
|
return {Bytes::NONE};
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
:returns: A string containing the full human-readable name of the destination, for an app_name and a number of aspects.
|
:returns: A string containing the full human-readable name of the destination, for an app_name and a number of aspects.
|
||||||
*/
|
*/
|
||||||
@ -169,7 +189,7 @@ Packet Destination::announce(const Bytes& app_data, bool path_response, const In
|
|||||||
// received via multiple paths. The difference in reception time will
|
// received via multiple paths. The difference in reception time will
|
||||||
// potentially also be useful in determining characteristics of the
|
// potentially also be useful in determining characteristics of the
|
||||||
// multiple available paths, and to choose the best one.
|
// multiple available paths, and to choose the best one.
|
||||||
//zextreme("Using cached announce data for answering path request with tag "+RNS.prettyhexrep(tag));
|
//z extreme("Using cached announce data for answering path request with tag "+RNS.prettyhexrep(tag));
|
||||||
announce_data << _object->_path_responses[tag].second;
|
announce_data << _object->_path_responses[tag].second;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -79,8 +79,10 @@ namespace RNS {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static Bytes hash(const Identity& identity, const char *app_name, const char *aspects);
|
|
||||||
static std::string expand_name(const Identity& identity, const char *app_name, const char *aspects);
|
static std::string expand_name(const Identity& identity, const char *app_name, const char *aspects);
|
||||||
|
static Bytes hash(const Identity& identity, const char *app_name, const char *aspects);
|
||||||
|
static Bytes app_and_aspects_from_name(const char* full_name);
|
||||||
|
static Bytes hash_from_name_and_identity(const char* full_name, const Identity& identity);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
//Packet announce(const Bytes& app_data = {}, bool path_response = false, const Interface& attached_interface = {Type::NONE}, const Bytes& tag = {}, bool send = true);
|
//Packet announce(const Bytes& app_data = {}, bool path_response = false, const Interface& attached_interface = {Type::NONE}, const Bytes& tag = {}, bool send = true);
|
||||||
@ -153,6 +155,7 @@ namespace RNS {
|
|||||||
inline Type::Destination::directions direction() const { assert(_object); return _object->_direction; }
|
inline Type::Destination::directions direction() const { assert(_object); return _object->_direction; }
|
||||||
inline Type::Destination::proof_strategies proof_strategy() const { assert(_object); return _object->_proof_strategy; }
|
inline Type::Destination::proof_strategies proof_strategy() const { assert(_object); return _object->_proof_strategy; }
|
||||||
inline const Bytes& hash() const { assert(_object); return _object->_hash; }
|
inline const Bytes& hash() const { assert(_object); return _object->_hash; }
|
||||||
|
inline void hash(const Bytes& hash) { assert(_object); _object->_hash = hash; _object->_hexhash = _object->_hash.toHex(); }
|
||||||
inline const Bytes& link_id() const { assert(_object); return _object->_link_id; }
|
inline const Bytes& link_id() const { assert(_object); return _object->_link_id; }
|
||||||
inline uint16_t mtu() const { assert(_object); return _object->_mtu; }
|
inline uint16_t mtu() const { assert(_object); return _object->_mtu; }
|
||||||
inline void mtu(uint16_t mtu) { assert(_object); _object->_mtu = mtu; }
|
inline void mtu(uint16_t mtu) { assert(_object); _object->_mtu = mtu; }
|
||||||
@ -170,7 +173,7 @@ namespace RNS {
|
|||||||
private:
|
private:
|
||||||
bool _accept_link_requests = true;
|
bool _accept_link_requests = true;
|
||||||
Callbacks _callbacks;
|
Callbacks _callbacks;
|
||||||
//z_request_handlers = {}
|
//z _request_handlers = {}
|
||||||
Type::Destination::types _type;
|
Type::Destination::types _type;
|
||||||
Type::Destination::directions _direction;
|
Type::Destination::directions _direction;
|
||||||
Type::Destination::proof_strategies _proof_strategy = Type::Destination::PROVE_NONE;
|
Type::Destination::proof_strategies _proof_strategy = Type::Destination::PROVE_NONE;
|
||||||
@ -178,7 +181,7 @@ namespace RNS {
|
|||||||
|
|
||||||
//std::vector<PathResponse> _path_responses;
|
//std::vector<PathResponse> _path_responses;
|
||||||
std::map<Bytes, PathResponse> _path_responses;
|
std::map<Bytes, PathResponse> _path_responses;
|
||||||
//z_links = []
|
//z _links = []
|
||||||
|
|
||||||
Identity _identity;
|
Identity _identity;
|
||||||
std::string _name;
|
std::string _name;
|
||||||
@ -190,8 +193,8 @@ namespace RNS {
|
|||||||
|
|
||||||
// CBA TODO when is _default_app_data a "callable"?
|
// CBA TODO when is _default_app_data a "callable"?
|
||||||
Bytes _default_app_data;
|
Bytes _default_app_data;
|
||||||
//z_callback = None
|
//z _callback = None
|
||||||
//z_proofcallback = None
|
//z _proofcallback = None
|
||||||
|
|
||||||
// CBA _link_id is expected by packet but only present in Link
|
// CBA _link_id is expected by packet but only present in Link
|
||||||
// CBA TODO determine if Link needs to inherit from Destination or vice-versa
|
// CBA TODO determine if Link needs to inherit from Destination or vice-versa
|
||||||
|
227
src/Identity.cpp
227
src/Identity.cpp
@ -1,8 +1,10 @@
|
|||||||
#include "Identity.h"
|
#include "Identity.h"
|
||||||
|
|
||||||
#include "Reticulum.h"
|
#include "Reticulum.h"
|
||||||
|
#include "Transport.h"
|
||||||
#include "Packet.h"
|
#include "Packet.h"
|
||||||
#include "Log.h"
|
#include "Log.h"
|
||||||
|
#include "Utilities/OS.h"
|
||||||
#include "Cryptography/X25519.h"
|
#include "Cryptography/X25519.h"
|
||||||
#include "Cryptography/HKDF.h"
|
#include "Cryptography/HKDF.h"
|
||||||
#include "Cryptography/Fernet.h"
|
#include "Cryptography/Fernet.h"
|
||||||
@ -12,6 +14,9 @@
|
|||||||
|
|
||||||
using namespace RNS;
|
using namespace RNS;
|
||||||
using namespace RNS::Type::Identity;
|
using namespace RNS::Type::Identity;
|
||||||
|
using namespace RNS::Utilities;
|
||||||
|
|
||||||
|
/*static*/ std::map<Bytes, Identity::IdentityEntry> Identity::_known_destinations;
|
||||||
|
|
||||||
Identity::Identity(bool create_keys) : _object(new Object()) {
|
Identity::Identity(bool create_keys) : _object(new Object()) {
|
||||||
if (create_keys) {
|
if (create_keys) {
|
||||||
@ -20,7 +25,6 @@ Identity::Identity(bool create_keys) : _object(new Object()) {
|
|||||||
extreme("Identity object created, this: " + std::to_string((uintptr_t)this) + ", data: " + std::to_string((uintptr_t)_object.get()));
|
extreme("Identity object created, this: " + std::to_string((uintptr_t)this) + ", data: " + std::to_string((uintptr_t)_object.get()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Identity::createKeys() {
|
void Identity::createKeys() {
|
||||||
assert(_object);
|
assert(_object);
|
||||||
|
|
||||||
@ -49,6 +53,215 @@ void Identity::createKeys() {
|
|||||||
verbose("Identity keys created for " + _object->_hash.toHex());
|
verbose("Identity keys created for " + _object->_hash.toHex());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Load a private key into the instance.
|
||||||
|
|
||||||
|
:param prv_bytes: The private key as *bytes*.
|
||||||
|
:returns: True if the key was loaded, otherwise False.
|
||||||
|
*/
|
||||||
|
bool Identity::load_private_key(const Bytes& prv_bytes) {
|
||||||
|
/*
|
||||||
|
assert(_object);
|
||||||
|
try {
|
||||||
|
//p self.prv_bytes = prv_bytes[:Identity.KEYSIZE//8//2]
|
||||||
|
_object->_prv_bytes = prv_bytes.left(Type::Identity::KEYSIZE/8/2);
|
||||||
|
_object->_prv = X25519PrivateKey::from_private_bytes(_object->_prv_bytes);
|
||||||
|
//p self.sig_prv_bytes = prv_bytes[Identity.KEYSIZE//8//2:]
|
||||||
|
_object->_sig_prv_bytes = prv_bytes.mid(Type::Identity::KEYSIZE/8/2);
|
||||||
|
_object->_sig_prv = Ed25519PrivateKey::from_private_bytes(_object->_sig_prv_bytes);
|
||||||
|
|
||||||
|
_object->_pub = _object->_prv.public_key();
|
||||||
|
_object->_pub_bytes = _object->_pub.public_bytes();
|
||||||
|
|
||||||
|
_object->_sig_pub = _object->_sig_prv.public_key();
|
||||||
|
_object->_sig_pub_bytes = _object->_sig_pub.public_bytes();
|
||||||
|
|
||||||
|
update_hashes();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
catch (std::exception& e) {
|
||||||
|
//p raise e
|
||||||
|
error("Failed to load identity key";
|
||||||
|
error("The contained exception was: " + e.what());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
// MOCK
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Load a public key into the instance.
|
||||||
|
|
||||||
|
:param pub_bytes: The public key as *bytes*.
|
||||||
|
:returns: True if the key was loaded, otherwise False.
|
||||||
|
*/
|
||||||
|
void Identity::load_public_key(const Bytes& pub_bytes) {
|
||||||
|
/*
|
||||||
|
assert(_object);
|
||||||
|
try {
|
||||||
|
//_pub_bytes = pub_bytes[:Identity.KEYSIZE//8//2]
|
||||||
|
_object->_pub_bytes = pub_bytes.left(Type::Identity::KEYSIZE/8/2);
|
||||||
|
//_sig_pub_bytes = pub_bytes[Identity.KEYSIZE//8//2:]
|
||||||
|
_object->_sig_pub_bytes = pub_bytes.mid(Type::Identity::KEYSIZE/8/2);
|
||||||
|
|
||||||
|
_object->_pub = X25519PublicKey::from_public_bytes(_object->_pub_bytes)
|
||||||
|
_object->_sig_pub = Ed25519PublicKey::from_public_bytes(_object->_sig_pub_bytes)
|
||||||
|
|
||||||
|
update_hashes();
|
||||||
|
}
|
||||||
|
catch (std::exception& e) {
|
||||||
|
error("Error while loading public key, the contained exception was: " + e.what());
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Identity::load(const char* path) {
|
||||||
|
/*
|
||||||
|
try:
|
||||||
|
with open(path, "rb") as key_file:
|
||||||
|
prv_bytes = key_file.read()
|
||||||
|
return self.load_private_key(prv_bytes)
|
||||||
|
return False
|
||||||
|
except Exception as e:
|
||||||
|
RNS.log("Error while loading identity from "+str(path), RNS.LOG_ERROR)
|
||||||
|
RNS.log("The contained exception was: "+str(e), RNS.LOG_ERROR)
|
||||||
|
*/
|
||||||
|
// MOCK
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*static*/ void Identity::remember(const Bytes& packet_hash, const Bytes& destination_hash, const Bytes& public_key, const Bytes& app_data /*= {Bytes::NONE}*/) {
|
||||||
|
if (public_key.size() != Type::Identity::KEYSIZE/8) {
|
||||||
|
throw std::invalid_argument("Can't remember " + destination_hash.toHex() + ", the public key size of " + std::to_string(public_key.size()) + " is not valid.");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
//_known_destinations[destination_hash] = {OS::time(), packet_hash, public_key, app_data};
|
||||||
|
_known_destinations.insert({destination_hash, {OS::time(), packet_hash, public_key, app_data}});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Recall identity for a destination hash.
|
||||||
|
|
||||||
|
:param destination_hash: Destination hash as *bytes*.
|
||||||
|
:returns: An :ref:`RNS.Identity<api-identity>` instance that can be used to create an outgoing :ref:`RNS.Destination<api-destination>`, or *None* if the destination is unknown.
|
||||||
|
*/
|
||||||
|
/*static*/ Identity Identity::recall(const Bytes& destination_hash) {
|
||||||
|
auto iter = _known_destinations.find(destination_hash);
|
||||||
|
if (iter != _known_destinations.end()) {
|
||||||
|
const IdentityEntry& identity_data = (*iter).second;
|
||||||
|
Identity identity(false);
|
||||||
|
identity.load_public_key(identity_data._public_key);
|
||||||
|
identity.app_data(identity_data._app_data);
|
||||||
|
return identity;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
Destination registered_destination(Transport::find_destination_from_hash(destination_hash));
|
||||||
|
if (registered_destination) {
|
||||||
|
Identity identity(false);
|
||||||
|
identity.load_public_key(registered_destination.identity().get_public_key());
|
||||||
|
identity.app_data({Bytes::NONE});
|
||||||
|
return identity;
|
||||||
|
}
|
||||||
|
return {Type::NONE};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Recall last heard app_data for a destination hash.
|
||||||
|
|
||||||
|
:param destination_hash: Destination hash as *bytes*.
|
||||||
|
:returns: *Bytes* containing app_data, or *None* if the destination is unknown.
|
||||||
|
*/
|
||||||
|
/*static*/ Bytes Identity::recall_app_data(const Bytes& destination_hash) {
|
||||||
|
auto iter = _known_destinations.find(destination_hash);
|
||||||
|
if (iter != _known_destinations.end()) {
|
||||||
|
const IdentityEntry& identity_data = (*iter).second;
|
||||||
|
return identity_data._app_data;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return {Bytes::NONE};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*static*/ void Identity::save_known_destinations() {
|
||||||
|
/*
|
||||||
|
// TODO: Improve the storage method so we don't have to
|
||||||
|
// deserialize and serialize the entire table on every
|
||||||
|
// save, but the only changes. It might be possible to
|
||||||
|
// simply overwrite on exit now that every local client
|
||||||
|
// disconnect triggers a data persist.
|
||||||
|
|
||||||
|
try:
|
||||||
|
if hasattr(Identity, "saving_known_destinations"):
|
||||||
|
wait_interval = 0.2
|
||||||
|
wait_timeout = 5
|
||||||
|
wait_start = time.time()
|
||||||
|
while Identity.saving_known_destinations:
|
||||||
|
time.sleep(wait_interval)
|
||||||
|
if time.time() > wait_start+wait_timeout:
|
||||||
|
RNS.log("Could not save known destinations to storage, waiting for previous save operation timed out.", RNS.LOG_ERROR)
|
||||||
|
return False
|
||||||
|
|
||||||
|
Identity.saving_known_destinations = True
|
||||||
|
save_start = time.time()
|
||||||
|
|
||||||
|
storage_known_destinations = {}
|
||||||
|
if os.path.isfile(RNS.Reticulum.storagepath+"/known_destinations"):
|
||||||
|
try:
|
||||||
|
file = open(RNS.Reticulum.storagepath+"/known_destinations","rb")
|
||||||
|
storage_known_destinations = umsgpack.load(file)
|
||||||
|
file.close()
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
|
||||||
|
for destination_hash in storage_known_destinations:
|
||||||
|
if not destination_hash in Identity.known_destinations:
|
||||||
|
Identity.known_destinations[destination_hash] = storage_known_destinations[destination_hash]
|
||||||
|
|
||||||
|
RNS.log("Saving "+str(len(Identity.known_destinations))+" known destinations to storage...", RNS.LOG_DEBUG)
|
||||||
|
file = open(RNS.Reticulum.storagepath+"/known_destinations","wb")
|
||||||
|
umsgpack.dump(Identity.known_destinations, file)
|
||||||
|
file.close()
|
||||||
|
|
||||||
|
save_time = time.time() - save_start
|
||||||
|
if save_time < 1:
|
||||||
|
time_str = str(round(save_time*1000,2))+"ms"
|
||||||
|
else:
|
||||||
|
time_str = str(round(save_time,2))+"s"
|
||||||
|
|
||||||
|
RNS.log("Saved known destinations to storage in "+time_str, RNS.LOG_DEBUG)
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
RNS.log("Error while saving known destinations to disk, the contained exception was: "+str(e), RNS.LOG_ERROR)
|
||||||
|
|
||||||
|
Identity.saving_known_destinations = False
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
|
/*static*/ void Identity::load_known_destinations() {
|
||||||
|
/*
|
||||||
|
if os.path.isfile(RNS.Reticulum.storagepath+"/known_destinations"):
|
||||||
|
try:
|
||||||
|
file = open(RNS.Reticulum.storagepath+"/known_destinations","rb")
|
||||||
|
loaded_known_destinations = umsgpack.load(file)
|
||||||
|
file.close()
|
||||||
|
|
||||||
|
Identity.known_destinations = {}
|
||||||
|
for known_destination in loaded_known_destinations:
|
||||||
|
if len(known_destination) == RNS.Reticulum.TRUNCATED_HASHLENGTH//8:
|
||||||
|
Identity.known_destinations[known_destination] = loaded_known_destinations[known_destination]
|
||||||
|
|
||||||
|
RNS.log("Loaded "+str(len(Identity.known_destinations))+" known destination from storage", RNS.LOG_VERBOSE)
|
||||||
|
except:
|
||||||
|
RNS.log("Error loading known destinations from disk, file will be recreated on exit", RNS.LOG_ERROR)
|
||||||
|
else:
|
||||||
|
RNS.log("Destinations file does not exist, no known destinations loaded", RNS.LOG_VERBOSE)
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
/*static*/ bool Identity::validate_announce(const Packet& packet) {
|
/*static*/ bool Identity::validate_announce(const Packet& packet) {
|
||||||
/*
|
/*
|
||||||
@ -132,7 +345,7 @@ Encrypts information for the identity.
|
|||||||
:returns: Ciphertext token as *bytes*.
|
:returns: Ciphertext token as *bytes*.
|
||||||
:raises: *KeyError* if the instance does not hold a public key.
|
:raises: *KeyError* if the instance does not hold a public key.
|
||||||
*/
|
*/
|
||||||
const Bytes Identity::encrypt(const Bytes& plaintext) {
|
const Bytes Identity::encrypt(const Bytes& plaintext) const {
|
||||||
assert(_object);
|
assert(_object);
|
||||||
debug("Identity::encrypt: encrypting data...");
|
debug("Identity::encrypt: encrypting data...");
|
||||||
if (!_object->_pub) {
|
if (!_object->_pub) {
|
||||||
@ -172,7 +385,7 @@ Decrypts information for the identity.
|
|||||||
:returns: Plaintext as *bytes*, or *None* if decryption fails.
|
:returns: Plaintext as *bytes*, or *None* if decryption fails.
|
||||||
:raises: *KeyError* if the instance does not hold a private key.
|
:raises: *KeyError* if the instance does not hold a private key.
|
||||||
*/
|
*/
|
||||||
const Bytes Identity::decrypt(const Bytes& ciphertext_token) {
|
const Bytes Identity::decrypt(const Bytes& ciphertext_token) const {
|
||||||
assert(_object);
|
assert(_object);
|
||||||
debug("Identity::decrypt: decrypting data...");
|
debug("Identity::decrypt: decrypting data...");
|
||||||
if (!_object->_prv) {
|
if (!_object->_prv) {
|
||||||
@ -226,7 +439,7 @@ Signs information by the identity.
|
|||||||
:returns: Signature as *bytes*.
|
:returns: Signature as *bytes*.
|
||||||
:raises: *KeyError* if the instance does not hold a private key.
|
:raises: *KeyError* if the instance does not hold a private key.
|
||||||
*/
|
*/
|
||||||
const Bytes Identity::sign(const Bytes& message) {
|
const Bytes Identity::sign(const Bytes& message) const {
|
||||||
assert(_object);
|
assert(_object);
|
||||||
if (!_object->_sig_prv) {
|
if (!_object->_sig_prv) {
|
||||||
throw std::runtime_error("Signing failed because identity does not hold a private key");
|
throw std::runtime_error("Signing failed because identity does not hold a private key");
|
||||||
@ -248,7 +461,7 @@ Validates the signature of a signed message.
|
|||||||
:returns: True if the signature is valid, otherwise False.
|
:returns: True if the signature is valid, otherwise False.
|
||||||
:raises: *KeyError* if the instance does not hold a public key.
|
:raises: *KeyError* if the instance does not hold a public key.
|
||||||
*/
|
*/
|
||||||
bool Identity::validate(const Bytes& signature, const Bytes& message) {
|
bool Identity::validate(const Bytes& signature, const Bytes& message) const {
|
||||||
assert(_object);
|
assert(_object);
|
||||||
if (_object->_pub) {
|
if (_object->_pub) {
|
||||||
try {
|
try {
|
||||||
@ -264,7 +477,7 @@ bool Identity::validate(const Bytes& signature, const Bytes& message) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Identity::prove(const Packet& packet, const Destination& destination /*= {Type::NONE}*/) {
|
void Identity::prove(const Packet& packet, const Destination& destination /*= {Type::NONE}*/) const {
|
||||||
assert(_object);
|
assert(_object);
|
||||||
Bytes signature(sign(packet.packet_hash()));
|
Bytes signature(sign(packet.packet_hash()));
|
||||||
Bytes proof_data;
|
Bytes proof_data;
|
||||||
@ -283,6 +496,6 @@ void Identity::prove(const Packet& packet, const Destination& destination /*= {T
|
|||||||
proof.send();
|
proof.send();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Identity::prove(const Packet& packet) {
|
void Identity::prove(const Packet& packet) const {
|
||||||
prove(packet, {Type::NONE});
|
prove(packet, {Type::NONE});
|
||||||
}
|
}
|
||||||
|
@ -8,9 +8,9 @@
|
|||||||
#include "Cryptography/X25519.h"
|
#include "Cryptography/X25519.h"
|
||||||
#include "Cryptography/Fernet.h"
|
#include "Cryptography/Fernet.h"
|
||||||
|
|
||||||
|
#include <map>
|
||||||
#include <memory>
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
namespace RNS {
|
namespace RNS {
|
||||||
|
|
||||||
@ -19,6 +19,23 @@ namespace RNS {
|
|||||||
|
|
||||||
class Identity {
|
class Identity {
|
||||||
|
|
||||||
|
private:
|
||||||
|
class IdentityEntry {
|
||||||
|
public:
|
||||||
|
IdentityEntry(uint64_t timestamp, const Bytes& packet_hash, const Bytes& public_key, const Bytes& app_data) :
|
||||||
|
_timestamp(timestamp),
|
||||||
|
_packet_hash(packet_hash),
|
||||||
|
_public_key(public_key),
|
||||||
|
_app_data(app_data)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
public:
|
||||||
|
uint64_t _timestamp = 0;
|
||||||
|
Bytes _packet_hash;
|
||||||
|
Bytes _public_key;
|
||||||
|
Bytes _app_data;
|
||||||
|
};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Identity(Type::NoneConstructor none) {
|
Identity(Type::NoneConstructor none) {
|
||||||
extreme("Identity NONE object created, this: " + std::to_string((uintptr_t)this) + ", data: " + std::to_string((uintptr_t)_object.get()));
|
extreme("Identity NONE object created, this: " + std::to_string((uintptr_t)this) + ", data: " + std::to_string((uintptr_t)_object.get()));
|
||||||
@ -45,20 +62,48 @@ namespace RNS {
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
void createKeys();
|
void createKeys();
|
||||||
|
|
||||||
|
/*
|
||||||
|
:returns: The private key as *bytes*
|
||||||
|
*/
|
||||||
|
inline const Bytes get_private_key() const {
|
||||||
|
assert(_object);
|
||||||
|
return _object->_prv_bytes + _object->_sig_prv_bytes;
|
||||||
|
}
|
||||||
/*
|
/*
|
||||||
:returns: The public key as *bytes*
|
:returns: The public key as *bytes*
|
||||||
*/
|
*/
|
||||||
inline const Bytes get_public_key() {
|
inline const Bytes get_public_key() const {
|
||||||
assert(_object);
|
assert(_object);
|
||||||
return _object->_pub_bytes + _object->_sig_pub_bytes;
|
return _object->_pub_bytes + _object->_sig_pub_bytes;
|
||||||
}
|
}
|
||||||
|
bool load_private_key(const Bytes& prv_bytes);
|
||||||
|
void load_public_key(const Bytes& pub_bytes);
|
||||||
inline void update_hashes() {
|
inline void update_hashes() {
|
||||||
assert(_object);
|
assert(_object);
|
||||||
_object->_hash = truncated_hash(get_public_key());
|
_object->_hash = truncated_hash(get_public_key());
|
||||||
debug("Identity::update_hashes: hash: " + _object->_hash.toHex());
|
debug("Identity::update_hashes: hash: " + _object->_hash.toHex());
|
||||||
_object->_hexhash = _object->_hash.toHex();
|
_object->_hexhash = _object->_hash.toHex();
|
||||||
};
|
};
|
||||||
|
bool load(const char* path);
|
||||||
|
|
||||||
|
inline const Bytes get_salt() const { assert(_object); return _object->_hash; }
|
||||||
|
inline const Bytes get_context() const { return {Bytes::NONE}; }
|
||||||
|
|
||||||
|
const Bytes encrypt(const Bytes& plaintext) const;
|
||||||
|
const Bytes decrypt(const Bytes& ciphertext_token) const;
|
||||||
|
const Bytes sign(const Bytes& message) const;
|
||||||
|
bool validate(const Bytes& signature, const Bytes& message) const;
|
||||||
|
// CBA following default for reference value requires inclusiion of header
|
||||||
|
//void prove(const Packet& packet, const Destination& destination = {Type::NONE}) const;
|
||||||
|
void prove(const Packet& packet, const Destination& destination) const;
|
||||||
|
void prove(const Packet& packet) const;
|
||||||
|
|
||||||
|
static void remember(const Bytes& packet_hash, const Bytes& destination_hash, const Bytes& public_key, const Bytes& app_data = {Bytes::NONE});
|
||||||
|
static Identity recall(const Bytes& destination_hash);
|
||||||
|
static Bytes recall_app_data(const Bytes& destination_hash);
|
||||||
|
static void save_known_destinations();
|
||||||
|
static void load_known_destinations();
|
||||||
/*
|
/*
|
||||||
Get a SHA-256 hash of passed data.
|
Get a SHA-256 hash of passed data.
|
||||||
|
|
||||||
@ -75,7 +120,7 @@ namespace RNS {
|
|||||||
:returns: Truncated SHA-256 hash as *bytes*
|
:returns: Truncated SHA-256 hash as *bytes*
|
||||||
*/
|
*/
|
||||||
static inline const Bytes truncated_hash(const Bytes& data) {
|
static inline const Bytes truncated_hash(const Bytes& data) {
|
||||||
//return Identity.full_hash(data)[:(Identity.TRUNCATED_HASHLENGTH//8)]
|
//p return Identity.full_hash(data)[:(Identity.TRUNCATED_HASHLENGTH//8)]
|
||||||
return full_hash(data).left(Type::Identity::TRUNCATED_HASHLENGTH/8);
|
return full_hash(data).left(Type::Identity::TRUNCATED_HASHLENGTH/8);
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
@ -90,24 +135,14 @@ namespace RNS {
|
|||||||
|
|
||||||
static bool validate_announce(const Packet& packet);
|
static bool validate_announce(const Packet& packet);
|
||||||
|
|
||||||
inline const Bytes get_salt() { assert(_object); return _object->_hash; }
|
|
||||||
inline const Bytes get_context() { return {Bytes::NONE}; }
|
|
||||||
|
|
||||||
const Bytes encrypt(const Bytes& plaintext);
|
|
||||||
const Bytes decrypt(const Bytes& ciphertext_token);
|
|
||||||
const Bytes sign(const Bytes& message);
|
|
||||||
bool validate(const Bytes& signature, const Bytes& message);
|
|
||||||
// CBA following default for reference value requires inclusiion of header
|
|
||||||
//void prove(const Packet& packet, const Destination& destination = {Type::NONE});
|
|
||||||
void prove(const Packet& packet, const Destination& destination);
|
|
||||||
void prove(const Packet& packet);
|
|
||||||
|
|
||||||
// getters/setters
|
// getters/setters
|
||||||
inline const Bytes& encryptionPrivateKey() const { assert(_object); return _object->_prv_bytes; }
|
inline const Bytes& encryptionPrivateKey() const { assert(_object); return _object->_prv_bytes; }
|
||||||
inline const Bytes& signingPrivateKey() const { assert(_object); return _object->_sig_prv_bytes; }
|
inline const Bytes& signingPrivateKey() const { assert(_object); return _object->_sig_prv_bytes; }
|
||||||
inline const Bytes& encryptionPublicKey() const { assert(_object); return _object->_prv_bytes; }
|
inline const Bytes& encryptionPublicKey() const { assert(_object); return _object->_prv_bytes; }
|
||||||
inline const Bytes& signingPublicKey() const { assert(_object); return _object->_sig_prv_bytes; }
|
inline const Bytes& signingPublicKey() const { assert(_object); return _object->_sig_prv_bytes; }
|
||||||
inline const Bytes& hash() const { assert(_object); return _object->_hash; }
|
inline const Bytes& hash() const { assert(_object); return _object->_hash; }
|
||||||
|
inline const Bytes& app_data() const { assert(_object); return _object->_app_data; }
|
||||||
|
inline void app_data(const Bytes& app_data) { assert(_object); _object->_app_data = app_data; }
|
||||||
inline std::string hexhash() const { assert(_object); return _object->_hexhash; }
|
inline std::string hexhash() const { assert(_object); return _object->_hexhash; }
|
||||||
|
|
||||||
inline std::string toString() const { assert(_object); return "{Identity:" + _object->_hash.toHex() + "}"; }
|
inline std::string toString() const { assert(_object); return "{Identity:" + _object->_hash.toHex() + "}"; }
|
||||||
@ -134,10 +169,14 @@ namespace RNS {
|
|||||||
Bytes _hash;
|
Bytes _hash;
|
||||||
std::string _hexhash;
|
std::string _hexhash;
|
||||||
|
|
||||||
|
Bytes _app_data;
|
||||||
|
|
||||||
friend class Identity;
|
friend class Identity;
|
||||||
};
|
};
|
||||||
std::shared_ptr<Object> _object;
|
std::shared_ptr<Object> _object;
|
||||||
|
|
||||||
|
static std::map<Bytes, IdentityEntry> _known_destinations;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
@ -403,14 +403,14 @@ bool Packet::send() {
|
|||||||
|
|
||||||
if (Transport::outbound(*this)) {
|
if (Transport::outbound(*this)) {
|
||||||
debug("Packet::send: successfully sent packet!!!");
|
debug("Packet::send: successfully sent packet!!!");
|
||||||
//zreturn self.receipt
|
//z return self.receipt
|
||||||
// MOCK
|
// MOCK
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
error("No interfaces could process the outbound packet");
|
error("No interfaces could process the outbound packet");
|
||||||
_object->_sent = false;
|
_object->_sent = false;
|
||||||
//z_receipt = None;
|
//z _receipt = None;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -432,14 +432,14 @@ bool Packet::resend() {
|
|||||||
|
|
||||||
if (Transport::outbound(*this)) {
|
if (Transport::outbound(*this)) {
|
||||||
debug("Packet::resend: successfully sent packet!!!");
|
debug("Packet::resend: successfully sent packet!!!");
|
||||||
//zreturn self.receipt
|
//z return self.receipt
|
||||||
// MOCK
|
// MOCK
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
error("No interfaces could process the outbound packet");
|
error("No interfaces could process the outbound packet");
|
||||||
_object->_sent = false;
|
_object->_sent = false;
|
||||||
//zself.receipt = None;
|
//z self.receipt = None;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -552,9 +552,9 @@ void PacketReceipt::check_timeout() {
|
|||||||
_object->_concluded_at = Utilities::OS::time();
|
_object->_concluded_at = Utilities::OS::time();
|
||||||
|
|
||||||
if (_object->_callbacks._timeout) {
|
if (_object->_callbacks._timeout) {
|
||||||
//zthread = threading.Thread(target=self.callbacks.timeout, args=(self,))
|
//z thread = threading.Thread(target=self.callbacks.timeout, args=(self,))
|
||||||
//zthread.daemon = True
|
//z thread.daemon = True
|
||||||
//zthread.start();
|
//z thread.start();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
25
src/Packet.h
25
src/Packet.h
@ -129,8 +129,27 @@ namespace RNS {
|
|||||||
Packet(const Packet& packet) : _object(packet._object) {
|
Packet(const Packet& packet) : _object(packet._object) {
|
||||||
extreme("Packet object copy created");
|
extreme("Packet object copy created");
|
||||||
}
|
}
|
||||||
Packet(const Destination& destination, const Interface& attached_interface, const Bytes& data, Type::Packet::types packet_type = Type::Packet::DATA, Type::Packet::context_types context = Type::Packet::CONTEXT_NONE, Type::Transport::types transport_type = Type::Transport::BROADCAST, Type::Packet::header_types header_type = Type::Packet::HEADER_1, const Bytes& transport_id = {Bytes::NONE}, bool create_receipt = true);
|
Packet(
|
||||||
Packet(const Destination& destination, const Bytes& data, Type::Packet::types packet_type = Type::Packet::DATA, Type::Packet::context_types context = Type::Packet::CONTEXT_NONE, Type::Transport::types transport_type = Type::Transport::BROADCAST, Type::Packet::header_types header_type = Type::Packet::HEADER_1, const Bytes& transport_id = {Bytes::NONE}, bool create_receipt = true) : Packet(destination, {Type::NONE}, data, packet_type, context, transport_type, header_type, transport_id, create_receipt) {}
|
const Destination& destination,
|
||||||
|
const Interface& attached_interface,
|
||||||
|
const Bytes& data,
|
||||||
|
Type::Packet::types packet_type = Type::Packet::DATA,
|
||||||
|
Type::Packet::context_types context = Type::Packet::CONTEXT_NONE,
|
||||||
|
Type::Transport::types transport_type = Type::Transport::BROADCAST,
|
||||||
|
Type::Packet::header_types header_type = Type::Packet::HEADER_1,
|
||||||
|
const Bytes& transport_id = {Bytes::NONE},
|
||||||
|
bool create_receipt = true
|
||||||
|
);
|
||||||
|
Packet(
|
||||||
|
const Destination& destination,
|
||||||
|
const Bytes& data,
|
||||||
|
Type::Packet::types packet_type = Type::Packet::DATA,
|
||||||
|
Type::Packet::context_types context = Type::Packet::CONTEXT_NONE,
|
||||||
|
Type::Transport::types transport_type = Type::Transport::BROADCAST,
|
||||||
|
Type::Packet::header_types header_type = Type::Packet::HEADER_1,
|
||||||
|
const Bytes& transport_id = {Bytes::NONE},
|
||||||
|
bool create_receipt = true
|
||||||
|
) : Packet(destination, {Type::NONE}, data, packet_type, context, transport_type, header_type, transport_id, create_receipt) {}
|
||||||
virtual ~Packet();
|
virtual ~Packet();
|
||||||
|
|
||||||
inline Packet& operator = (const Packet& packet) {
|
inline Packet& operator = (const Packet& packet) {
|
||||||
@ -165,7 +184,7 @@ namespace RNS {
|
|||||||
const Bytes get_hash() const;
|
const Bytes get_hash() const;
|
||||||
const Bytes getTruncatedHash() const;
|
const Bytes getTruncatedHash() const;
|
||||||
const Bytes get_hashable_part() const;
|
const Bytes get_hashable_part() const;
|
||||||
//zProofDestination& generate_proof_destination();
|
//z ProofDestination& generate_proof_destination();
|
||||||
|
|
||||||
// getters/setters
|
// getters/setters
|
||||||
inline const Destination& destination() const { assert(_object); return _object->_destination; }
|
inline const Destination& destination() const { assert(_object); return _object->_destination; }
|
||||||
|
@ -14,11 +14,22 @@
|
|||||||
#include <time.h>
|
#include <time.h>
|
||||||
|
|
||||||
using namespace RNS;
|
using namespace RNS;
|
||||||
|
using namespace RNS::Type::Transport;
|
||||||
using namespace RNS::Utilities;
|
using namespace RNS::Utilities;
|
||||||
|
|
||||||
|
#if defined(INTERFACES_SET)
|
||||||
///*static*/ std::set<std::reference_wrapper<const Interface>, std::less<const Interface>> Transport::_interfaces;
|
///*static*/ std::set<std::reference_wrapper<const Interface>, std::less<const Interface>> Transport::_interfaces;
|
||||||
|
/*static*/ std::set<std::reference_wrapper<Interface>, std::less<Interface>> Transport::_interfaces;
|
||||||
|
#elif defined(INTERFACES_LIST)
|
||||||
/*static*/ std::list<std::reference_wrapper<Interface>> Transport::_interfaces;
|
/*static*/ std::list<std::reference_wrapper<Interface>> Transport::_interfaces;
|
||||||
|
#elif defined(INTERFACES_MAP)
|
||||||
|
/*static*/ std::map<Bytes, Interface&> Transport::_interfaces;
|
||||||
|
#endif
|
||||||
|
#if defined(DESTINATIONS_SET)
|
||||||
/*static*/ std::set<Destination> Transport::_destinations;
|
/*static*/ std::set<Destination> Transport::_destinations;
|
||||||
|
#elif defined(DESTINATIONS_MAP)
|
||||||
|
/*static*/ std::map<Bytes, Destination> Transport::_destinations;
|
||||||
|
#endif
|
||||||
/*static*/ std::set<Link> Transport::_pending_links;
|
/*static*/ std::set<Link> Transport::_pending_links;
|
||||||
/*static*/ std::set<Link> Transport::_active_links;
|
/*static*/ std::set<Link> Transport::_active_links;
|
||||||
/*static*/ std::set<Bytes> Transport::_packet_hashlist;
|
/*static*/ std::set<Bytes> Transport::_packet_hashlist;
|
||||||
@ -31,12 +42,16 @@ using namespace RNS::Utilities;
|
|||||||
/*static*/ std::set<HAnnounceHandler> Transport::_announce_handlers;
|
/*static*/ std::set<HAnnounceHandler> Transport::_announce_handlers;
|
||||||
/*static*/ std::set<Bytes> Transport::_path_requests;
|
/*static*/ std::set<Bytes> Transport::_path_requests;
|
||||||
|
|
||||||
|
/*static*/ std::map<Bytes, Transport::PathRequestEntry> Transport::_discovery_path_requests;
|
||||||
/*static*/ uint16_t Transport::_max_pr_taXgxs = 32000;
|
/*static*/ uint16_t Transport::_max_pr_taXgxs = 32000;
|
||||||
|
|
||||||
/*static*/ std::set<Destination> Transport::_control_destinations;
|
/*static*/ std::set<Destination> Transport::_control_destinations;
|
||||||
/*static*/ std::set<Bytes> Transport::_control_hashes;
|
/*static*/ std::set<Bytes> Transport::_control_hashes;
|
||||||
|
|
||||||
/*static*/ std::set<Interface> Transport::_local_client_interfaces;
|
///*static*/ std::set<Interface> Transport::_local_client_interfaces;
|
||||||
|
/*static*/ std::set<std::reference_wrapper<const Interface>, std::less<const Interface>> Transport::_local_client_interfaces;
|
||||||
|
|
||||||
|
/*static*/ std::map<Bytes, const Interface&> Transport::_pending_local_path_requests;
|
||||||
|
|
||||||
/*static*/ uint16_t Transport::_LOCAL_CLIENT_CACHE_MAXSIZE = 512;
|
/*static*/ uint16_t Transport::_LOCAL_CLIENT_CACHE_MAXSIZE = 512;
|
||||||
|
|
||||||
@ -62,15 +77,15 @@ using namespace RNS::Utilities;
|
|||||||
_owner = reticulum_instance;
|
_owner = reticulum_instance;
|
||||||
|
|
||||||
if (!_identity) {
|
if (!_identity) {
|
||||||
//ztransport_identity_path = Reticulum::storagepath+"/transport_identity"
|
//z transport_identity_path = Reticulum::storagepath+"/transport_identity"
|
||||||
//zif (os.path.isfile(transport_identity_path)) {
|
//z if (os.path.isfile(transport_identity_path)) {
|
||||||
//z identity = Identity.from_file(transport_identity_path);
|
//z identity = Identity.from_file(transport_identity_path);
|
||||||
//z}
|
//z }
|
||||||
|
|
||||||
if (!_identity) {
|
if (!_identity) {
|
||||||
verbose("No valid Transport Identity in storage, creating...");
|
verbose("No valid Transport Identity in storage, creating...");
|
||||||
_identity = new Identity();
|
_identity = new Identity();
|
||||||
//z_identity.to_file(transport_identity_path);
|
//z _identity.to_file(transport_identity_path);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
verbose("Loaded Transport Identity from storage");
|
verbose("Loaded Transport Identity from storage");
|
||||||
@ -714,7 +729,13 @@ using namespace RNS::Utilities;
|
|||||||
else {
|
else {
|
||||||
extreme("Transport::outbound: Path to destination is unknown");
|
extreme("Transport::outbound: Path to destination is unknown");
|
||||||
bool stored_hash = false;
|
bool stored_hash = false;
|
||||||
|
#if defined(INTERFACES_SET)
|
||||||
for (const Interface& interface : _interfaces) {
|
for (const Interface& interface : _interfaces) {
|
||||||
|
#elif defined(INTERFACES_LIST)
|
||||||
|
for (Interface& interface : _interfaces) {
|
||||||
|
#elif defined(INTERFACES_MAP)
|
||||||
|
for (auto& [hash, interface] : _interfaces) {
|
||||||
|
#endif
|
||||||
extreme("Transport::outbound: Checking interface " + interface.toString());
|
extreme("Transport::outbound: Checking interface " + interface.toString());
|
||||||
if (interface.OUT()) {
|
if (interface.OUT()) {
|
||||||
bool should_transmit = true;
|
bool should_transmit = true;
|
||||||
@ -724,9 +745,9 @@ using namespace RNS::Utilities;
|
|||||||
should_transmit = false;
|
should_transmit = false;
|
||||||
}
|
}
|
||||||
// CBA Destination has no member attached_interface
|
// CBA Destination has no member attached_interface
|
||||||
//zif (interface != packet.destination().attached_interface()) {
|
//z if (interface != packet.destination().attached_interface()) {
|
||||||
//z should_transmit = false;
|
//z should_transmit = false;
|
||||||
//z}
|
//z }
|
||||||
}
|
}
|
||||||
|
|
||||||
if (packet.attached_interface() && interface != packet.attached_interface()) {
|
if (packet.attached_interface() && interface != packet.attached_interface()) {
|
||||||
@ -743,6 +764,7 @@ using namespace RNS::Utilities;
|
|||||||
else if (interface.mode() == Type::Interface::MODE_ROAMING) {
|
else if (interface.mode() == Type::Interface::MODE_ROAMING) {
|
||||||
//local_destination = next((d for d in Transport.destinations if d.hash == packet.destination_hash), None)
|
//local_destination = next((d for d in Transport.destinations if d.hash == packet.destination_hash), None)
|
||||||
//Destination local_destination({Type::NONE});
|
//Destination local_destination({Type::NONE});
|
||||||
|
#if defined(DESTINATIONS_SET)
|
||||||
bool found_local = false;
|
bool found_local = false;
|
||||||
for (auto& destination : _destinations) {
|
for (auto& destination : _destinations) {
|
||||||
if (destination.hash() == packet.destination_hash()) {
|
if (destination.hash() == packet.destination_hash()) {
|
||||||
@ -754,6 +776,13 @@ using namespace RNS::Utilities;
|
|||||||
//if local_destination != None:
|
//if local_destination != None:
|
||||||
//if (local_destination) {
|
//if (local_destination) {
|
||||||
if (found_local) {
|
if (found_local) {
|
||||||
|
#elif defined(DESTINATIONS_MAP)
|
||||||
|
auto iter = _destinations.find(packet.destination_hash());
|
||||||
|
//if (iter != _destinations.end()) {
|
||||||
|
// local_destination = (*iter).second;
|
||||||
|
//}
|
||||||
|
if (iter != _destinations.end()) {
|
||||||
|
#endif
|
||||||
//extreme("Allowing announce broadcast on roaming-mode interface from instance-local destination");
|
//extreme("Allowing announce broadcast on roaming-mode interface from instance-local destination");
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@ -786,6 +815,7 @@ using namespace RNS::Utilities;
|
|||||||
// next(iterable, default)
|
// next(iterable, default)
|
||||||
// list comprehension: [x for x in xyz if x in a]
|
// list comprehension: [x for x in xyz if x in a]
|
||||||
// CBA TODO confirm that above pattern just selects the first matching destination
|
// CBA TODO confirm that above pattern just selects the first matching destination
|
||||||
|
#if defined(DESTINATIONS_SET)
|
||||||
//Destination local_destination({Typeestination::NONE});
|
//Destination local_destination({Typeestination::NONE});
|
||||||
bool found_local = false;
|
bool found_local = false;
|
||||||
for (auto& destination : _destinations) {
|
for (auto& destination : _destinations) {
|
||||||
@ -798,6 +828,10 @@ using namespace RNS::Utilities;
|
|||||||
//if local_destination != None:
|
//if local_destination != None:
|
||||||
//if (local_destination) {
|
//if (local_destination) {
|
||||||
if (found_local) {
|
if (found_local) {
|
||||||
|
#elif defined(DESTINATIONS_MAP)
|
||||||
|
auto iter = _destinations.find(packet.destination_hash());
|
||||||
|
if (iter != _destinations.end()) {
|
||||||
|
#endif
|
||||||
//extreme("Allowing announce broadcast on boundary-mode interface from instance-local destination");
|
//extreme("Allowing announce broadcast on boundary-mode interface from instance-local destination");
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@ -840,7 +874,11 @@ using namespace RNS::Utilities;
|
|||||||
if (!queued_announces && outbound_time > interface.announce_allowed_at()) {
|
if (!queued_announces && outbound_time > interface.announce_allowed_at()) {
|
||||||
uint16_t tx_time = (packet.raw().size() * 8) / interface.bitrate();
|
uint16_t tx_time = (packet.raw().size() * 8) / interface.bitrate();
|
||||||
uint16_t wait_time = (tx_time / interface.announce_cap());
|
uint16_t wait_time = (tx_time / interface.announce_cap());
|
||||||
|
#if defined(INTERFACES_SET)
|
||||||
const_cast<Interface&>(interface).announce_allowed_at(outbound_time + wait_time);
|
const_cast<Interface&>(interface).announce_allowed_at(outbound_time + wait_time);
|
||||||
|
#else
|
||||||
|
interface.announce_allowed_at(outbound_time + wait_time);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
should_transmit = false;
|
should_transmit = false;
|
||||||
@ -869,13 +907,17 @@ using namespace RNS::Utilities;
|
|||||||
);
|
);
|
||||||
|
|
||||||
queued_announces = (interface.announce_queue().size() > 0);
|
queued_announces = (interface.announce_queue().size() > 0);
|
||||||
|
#if defined(INTERFACES_SET)
|
||||||
const_cast<Interface&>(interface).add_announce(entry);
|
const_cast<Interface&>(interface).add_announce(entry);
|
||||||
|
#else
|
||||||
|
interface.add_announce(entry);
|
||||||
|
#endif
|
||||||
|
|
||||||
if (!queued_announces) {
|
if (!queued_announces) {
|
||||||
uint64_t wait_time = std::max(interface.announce_allowed_at() - OS::time(), (uint64_t)0);
|
uint64_t wait_time = std::max(interface.announce_allowed_at() - OS::time(), (uint64_t)0);
|
||||||
// CBA TODO THREAD?
|
// CBA TODO THREAD?
|
||||||
//ztimer = threading.Timer(wait_time, interface.process_announce_queue)
|
//z timer = threading.Timer(wait_time, interface.process_announce_queue)
|
||||||
//ztimer.start()
|
//z timer.start()
|
||||||
|
|
||||||
std::string wait_time_str;
|
std::string wait_time_str;
|
||||||
if (wait_time < 1000) {
|
if (wait_time < 1000) {
|
||||||
@ -925,12 +967,16 @@ using namespace RNS::Utilities;
|
|||||||
|
|
||||||
// TODO: Re-evaluate potential for blocking
|
// TODO: Re-evaluate potential for blocking
|
||||||
// def send_packet():
|
// def send_packet():
|
||||||
// Transport.transmit(const_cast<Interface&>(interface), packet.raw)
|
// Transport.transmit(interface, packet.raw)
|
||||||
// thread = threading.Thread(target=send_packet)
|
// thread = threading.Thread(target=send_packet)
|
||||||
// thread.daemon = True
|
// thread.daemon = True
|
||||||
// thread.start()
|
// thread.start()
|
||||||
|
|
||||||
|
#if defined(INTERFACES_SET)
|
||||||
transmit(const_cast<Interface&>(interface), packet.raw());
|
transmit(const_cast<Interface&>(interface), packet.raw());
|
||||||
|
#else
|
||||||
|
transmit(interface, packet.raw());
|
||||||
|
#endif
|
||||||
sent = true;
|
sent = true;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@ -1197,7 +1243,7 @@ using namespace RNS::Utilities;
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//proof_for_local_client = (packet.destination_hash in Transport.reverse_table) and (Transport.reverse_table[packet.destination_hash][0] in Transport.local_client_interfaces)
|
//p roof_for_local_client = (packet.destination_hash in Transport.reverse_table) and (Transport.reverse_table[packet.destination_hash][0] in Transport.local_client_interfaces)
|
||||||
bool proof_for_local_client = false;
|
bool proof_for_local_client = false;
|
||||||
auto reverse_iter = _reverse_table.find(packet.destination_hash());
|
auto reverse_iter = _reverse_table.find(packet.destination_hash());
|
||||||
if (reverse_iter != _reverse_table.end()) {
|
if (reverse_iter != _reverse_table.end()) {
|
||||||
@ -1214,17 +1260,27 @@ using namespace RNS::Utilities;
|
|||||||
if (packet.destination_type() == Type::Destination::PLAIN && packet.transport_type() == Type::Transport::BROADCAST) {
|
if (packet.destination_type() == Type::Destination::PLAIN && packet.transport_type() == Type::Transport::BROADCAST) {
|
||||||
// Send to all interfaces except the originator
|
// Send to all interfaces except the originator
|
||||||
if (from_local_client) {
|
if (from_local_client) {
|
||||||
|
#if defined(INTERFACES_SET)
|
||||||
for (const Interface& interface : _interfaces) {
|
for (const Interface& interface : _interfaces) {
|
||||||
|
#elif defined(INTERFACES_LIST)
|
||||||
|
for (Interface& interface : _interfaces) {
|
||||||
|
#elif defined(INTERFACES_MAP)
|
||||||
|
for (auto& [hash, interface] : _interfaces) {
|
||||||
|
#endif
|
||||||
if (interface != packet.receiving_interface()) {
|
if (interface != packet.receiving_interface()) {
|
||||||
extreme("Transport::inbound: Broadcasting packet on " + interface.toString());
|
extreme("Transport::inbound: Broadcasting packet on " + interface.toString());
|
||||||
|
#if defined(INTERFACES_SET)
|
||||||
transmit(const_cast<Interface&>(interface), packet.raw());
|
transmit(const_cast<Interface&>(interface), packet.raw());
|
||||||
|
#else
|
||||||
|
transmit(interface, packet.raw());
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// If the packet was not from a local client, send
|
// If the packet was not from a local client, send
|
||||||
// it directly to all local clients
|
// it directly to all local clients
|
||||||
else {
|
else {
|
||||||
for (auto& interface : _local_client_interfaces) {
|
for (const Interface& interface : _local_client_interfaces) {
|
||||||
extreme("Transport::inbound: Broadcasting packet on " + interface.toString());
|
extreme("Transport::inbound: Broadcasting packet on " + interface.toString());
|
||||||
transmit(const_cast<Interface&>(interface), packet.raw());
|
transmit(const_cast<Interface&>(interface), packet.raw());
|
||||||
}
|
}
|
||||||
@ -1329,7 +1385,11 @@ using namespace RNS::Utilities;
|
|||||||
);
|
);
|
||||||
_reverse_table.insert({packet.getTruncatedHash(), reverse_entry});
|
_reverse_table.insert({packet.getTruncatedHash(), reverse_entry});
|
||||||
}
|
}
|
||||||
|
#if defined(INTERFACES_SET)
|
||||||
transmit(const_cast<Interface&>(outbound_interface), new_raw);
|
transmit(const_cast<Interface&>(outbound_interface), new_raw);
|
||||||
|
#else
|
||||||
|
transmit(outbound_interface, new_raw);
|
||||||
|
#endif
|
||||||
destination_entry._timestamp = OS::time();
|
destination_entry._timestamp = OS::time();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@ -1401,6 +1461,7 @@ using namespace RNS::Utilities;
|
|||||||
extreme("Transport::inbound: Packet is ANNOUNCE");
|
extreme("Transport::inbound: Packet is ANNOUNCE");
|
||||||
Bytes received_from;
|
Bytes received_from;
|
||||||
//p local_destination = next((d for d in Transport.destinations if d.hash == packet.destination_hash), None)
|
//p local_destination = next((d for d in Transport.destinations if d.hash == packet.destination_hash), None)
|
||||||
|
#if defined(DESTINATIONS_SET)
|
||||||
//Destination local_destination({Type::NONE});
|
//Destination local_destination({Type::NONE});
|
||||||
bool found_local = false;
|
bool found_local = false;
|
||||||
for (auto& destination : _destinations) {
|
for (auto& destination : _destinations) {
|
||||||
@ -1413,6 +1474,10 @@ using namespace RNS::Utilities;
|
|||||||
//if local_destination == None and RNS.Identity.validate_announce(packet):
|
//if local_destination == None and RNS.Identity.validate_announce(packet):
|
||||||
//if (!local_destination && Identity::validate_announce(packet)) {
|
//if (!local_destination && Identity::validate_announce(packet)) {
|
||||||
if (!found_local && Identity::validate_announce(packet)) {
|
if (!found_local && Identity::validate_announce(packet)) {
|
||||||
|
#elif defined(DESTINATIONS_MAP)
|
||||||
|
auto iter = _destinations.find(packet.destination_hash());
|
||||||
|
if (iter == _destinations.end() && Identity::validate_announce(packet)) {
|
||||||
|
#endif
|
||||||
extreme("Transport::inbound: Packet is announce for non-local destination, processing...");
|
extreme("Transport::inbound: Packet is announce for non-local destination, processing...");
|
||||||
if (packet.transport_id()) {
|
if (packet.transport_id()) {
|
||||||
received_from = packet.transport_id();
|
received_from = packet.transport_id();
|
||||||
@ -1427,7 +1492,7 @@ using namespace RNS::Utilities;
|
|||||||
if ((packet.hops() - 1) == announce_entry._hops) {
|
if ((packet.hops() - 1) == announce_entry._hops) {
|
||||||
debug("Heard a local rebroadcast of announce for " + packet.destination_hash().toHex());
|
debug("Heard a local rebroadcast of announce for " + packet.destination_hash().toHex());
|
||||||
announce_entry._local_rebroadcasts += 1;
|
announce_entry._local_rebroadcasts += 1;
|
||||||
if (announce_entry._local_rebroadcasts >= Transport::LOCAL_REBROADCASTS_MAX) {
|
if (announce_entry._local_rebroadcasts >= LOCAL_REBROADCASTS_MAX) {
|
||||||
debug("Max local rebroadcasts of announce for " + packet.destination_hash().toHex() + " reached, dropping announce from our table");
|
debug("Max local rebroadcasts of announce for " + packet.destination_hash().toHex() + " reached, dropping announce from our table");
|
||||||
_announce_table.erase(packet.destination_hash());
|
_announce_table.erase(packet.destination_hash());
|
||||||
}
|
}
|
||||||
@ -1453,6 +1518,7 @@ using namespace RNS::Utilities;
|
|||||||
// First, check that the announce is not for a destination
|
// First, check that the announce is not for a destination
|
||||||
// local to this system, and that hops are less than the max
|
// local to this system, and that hops are less than the max
|
||||||
//if (not any(packet.destination_hash == d.hash for d in Transport.destinations) and packet.hops < Transport.PATHFINDER_M+1):
|
//if (not any(packet.destination_hash == d.hash for d in Transport.destinations) and packet.hops < Transport.PATHFINDER_M+1):
|
||||||
|
#if defined(DESTINATIONS_SET)
|
||||||
bool found_local = false;
|
bool found_local = false;
|
||||||
for (auto& destination : _destinations) {
|
for (auto& destination : _destinations) {
|
||||||
if (destination.hash() == packet.destination_hash()) {
|
if (destination.hash() == packet.destination_hash()) {
|
||||||
@ -1460,18 +1526,24 @@ using namespace RNS::Utilities;
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!found_local && packet.hops() < (Transport::PATHFINDER_M+1)) {
|
if (!found_local && packet.hops() < (PATHFINDER_M+1)) {
|
||||||
|
#elif defined(DESTINATIONS_MAP)
|
||||||
|
auto iter = _destinations.find(packet.destination_hash());
|
||||||
|
if (iter == _destinations.end() && packet.hops() < (PATHFINDER_M+1)) {
|
||||||
|
#endif
|
||||||
extreme("Transport::inbound: Packet is announce for non-local destination, processing...");
|
extreme("Transport::inbound: Packet is announce for non-local destination, processing...");
|
||||||
/*
|
|
||||||
uint64_t announce_emitted = Transport::announce_emitted(packet);
|
uint64_t announce_emitted = Transport::announce_emitted(packet);
|
||||||
|
|
||||||
//prandom_blob = packet.data[RNS.Identity.KEYSIZE//8+RNS.Identity.NAME_HASH_LENGTH//8:RNS.Identity.KEYSIZE//8+RNS.Identity.NAME_HASH_LENGTH//8+10]
|
//p random_blob = packet.data[RNS.Identity.KEYSIZE//8+RNS.Identity.NAME_HASH_LENGTH//8:RNS.Identity.KEYSIZE//8+RNS.Identity.NAME_HASH_LENGTH//8+10]
|
||||||
Bytes random_blob = packet.data().mid(Identity::KEYSIZE/8 + Identity::NAME_HASH_LENGTH/8, 10);
|
Bytes random_blob = packet.data().mid(Type::Identity::KEYSIZE/8 + Type::Identity::NAME_HASH_LENGTH/8, 10);
|
||||||
//prandom_blobs = []
|
//p random_blobs = []
|
||||||
|
std::set<Bytes> empty_random_blobs;
|
||||||
|
std::set<Bytes>& random_blobs = empty_random_blobs;
|
||||||
auto iter = _destination_table.find(packet.destination_hash());
|
auto iter = _destination_table.find(packet.destination_hash());
|
||||||
if (iter != _destination_table.end()) {
|
if (iter != _destination_table.end()) {
|
||||||
DestinationEntry destination_entry = (*iter).second;
|
DestinationEntry destination_entry = (*iter).second;
|
||||||
//prandom_blobs = Transport.destination_table[packet.destination_hash][4]
|
//p random_blobs = Transport.destination_table[packet.destination_hash][4]
|
||||||
|
random_blobs = destination_entry._random_blobs;
|
||||||
|
|
||||||
// If we already have a path to the announced
|
// If we already have a path to the announced
|
||||||
// destination, but the hop count is equal or
|
// destination, but the hop count is equal or
|
||||||
@ -1482,8 +1554,8 @@ using namespace RNS::Utilities;
|
|||||||
// replayed to forge paths.
|
// replayed to forge paths.
|
||||||
// TODO: Check whether this approach works
|
// TODO: Check whether this approach works
|
||||||
// under all circumstances
|
// under all circumstances
|
||||||
//pif not random_blob in random_blobs:
|
//p if not random_blob in random_blobs:
|
||||||
if (destination_entry._random_blobs.find(random_blob) == destination_entry._random_blobs.end()) {
|
if (random_blobs.find(random_blob) == random_blobs.end()) {
|
||||||
should_add = true;
|
should_add = true;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@ -1499,9 +1571,9 @@ using namespace RNS::Utilities;
|
|||||||
uint64_t path_expires = destination_entry._expires;
|
uint64_t path_expires = destination_entry._expires;
|
||||||
|
|
||||||
uint64_t path_announce_emitted = 0;
|
uint64_t path_announce_emitted = 0;
|
||||||
for (const Bytes& path_random_blob : destination_entry._random_blobs) {
|
for (const Bytes& path_random_blob : random_blobs) {
|
||||||
//path_announce_emitted = std::max(path_announce_emitted, int.from_bytes(path_random_blob[5:10], "big"))
|
//p path_announce_emitted = max(path_announce_emitted, int.from_bytes(path_random_blob[5:10], "big"))
|
||||||
//zpath_announce_emitted = std::max(path_announce_emitted, int.from_bytes(path_random_blob[5:10], "big"))
|
//z path_announce_emitted = std::max(path_announce_emitted, int.from_bytes(path_random_blob[5:10], "big"));
|
||||||
if (path_announce_emitted >= announce_emitted) {
|
if (path_announce_emitted >= announce_emitted) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -1511,7 +1583,7 @@ using namespace RNS::Utilities;
|
|||||||
// We also check that the announce is
|
// We also check that the announce is
|
||||||
// different from ones we've already heard,
|
// different from ones we've already heard,
|
||||||
// to avoid loops in the network
|
// to avoid loops in the network
|
||||||
if (destination_entry._random_blobs.find(random_blob) == destination_entry._random_blobs.end()) {
|
if (random_blobs.find(random_blob) == random_blobs.end()) {
|
||||||
// TODO: Check that this ^ approach actually
|
// TODO: Check that this ^ approach actually
|
||||||
// works under all circumstances
|
// works under all circumstances
|
||||||
debug("Replacing destination table entry for " + packet.destination_hash().toHex() + " with new announce due to expired path");
|
debug("Replacing destination table entry for " + packet.destination_hash().toHex() + " with new announce due to expired path");
|
||||||
@ -1523,7 +1595,7 @@ using namespace RNS::Utilities;
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (announce_emitted > path_announce_emitted) {
|
if (announce_emitted > path_announce_emitted) {
|
||||||
if (destination_entry._random_blobs.find(random_blob) == destination_entry._random_blobs.end()) {
|
if (random_blobs.find(random_blob) == random_blobs.end()) {
|
||||||
debug("Replacing destination table entry for " + packet.destination_hash().toHex() + " with new announce, since it was more recently emitted");
|
debug("Replacing destination table entry for " + packet.destination_hash().toHex() + " with new announce, since it was more recently emitted");
|
||||||
should_add = true;
|
should_add = true;
|
||||||
}
|
}
|
||||||
@ -1534,7 +1606,6 @@ using namespace RNS::Utilities;
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
else {
|
else {
|
||||||
// If this destination is unknown in our table
|
// If this destination is unknown in our table
|
||||||
// we should add it
|
// we should add it
|
||||||
@ -1546,7 +1617,7 @@ using namespace RNS::Utilities;
|
|||||||
|
|
||||||
bool rate_blocked = false;
|
bool rate_blocked = false;
|
||||||
|
|
||||||
|
/*
|
||||||
if packet.context != RNS.Packet.PATH_RESPONSE and packet.receiving_interface.announce_rate_target != None:
|
if packet.context != RNS.Packet.PATH_RESPONSE and packet.receiving_interface.announce_rate_target != None:
|
||||||
if not packet.destination_hash in Transport.announce_rate_table:
|
if not packet.destination_hash in Transport.announce_rate_table:
|
||||||
rate_entry = { "last": now, "rate_violations": 0, "blocked_until": 0, "timestamps": [now]}
|
rate_entry = { "last": now, "rate_violations": 0, "blocked_until": 0, "timestamps": [now]}
|
||||||
@ -1579,7 +1650,7 @@ using namespace RNS::Utilities;
|
|||||||
|
|
||||||
else:
|
else:
|
||||||
rate_blocked = True
|
rate_blocked = True
|
||||||
|
*/
|
||||||
|
|
||||||
uint8_t retries = 0;
|
uint8_t retries = 0;
|
||||||
uint8_t announce_hops = packet.hops();
|
uint8_t announce_hops = packet.hops();
|
||||||
@ -1587,36 +1658,35 @@ using namespace RNS::Utilities;
|
|||||||
bool block_rebroadcasts = false;
|
bool block_rebroadcasts = false;
|
||||||
Interface attached_interface = {Type::NONE};
|
Interface attached_interface = {Type::NONE};
|
||||||
|
|
||||||
uint64_t retransmit_timeout = now + (RNS::Cryptography::random() * Transport::PATHFINDER_RW);
|
uint64_t retransmit_timeout = now + (RNS::Cryptography::random() * PATHFINDER_RW);
|
||||||
|
|
||||||
uint64_t expires;
|
uint64_t expires;
|
||||||
if (packet.receiving_interface().mode() == Type::Interface::MODE_ACCESS_POINT) {
|
if (packet.receiving_interface().mode() == Type::Interface::MODE_ACCESS_POINT) {
|
||||||
expires = now + Transport::AP_PATH_TIME;
|
expires = now + AP_PATH_TIME;
|
||||||
}
|
}
|
||||||
else if (packet.receiving_interface().mode() == Type::Interface::MODE_ROAMING) {
|
else if (packet.receiving_interface().mode() == Type::Interface::MODE_ROAMING) {
|
||||||
expires = now + Transport::ROAMING_PATH_TIME;
|
expires = now + ROAMING_PATH_TIME;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
expires = now + Transport::PATHFINDER_E;
|
expires = now + PATHFINDER_E;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::set<Bytes> random_blobs;
|
|
||||||
random_blobs.insert(random_blob);
|
random_blobs.insert(random_blob);
|
||||||
|
|
||||||
if (Reticulum::transport_enabled() || from_local_client(packet) && packet.context() != Type::Packet::PATH_RESPONSE) {
|
if ((Reticulum::transport_enabled() || Transport::from_local_client(packet)) && packet.context() != Type::Packet::PATH_RESPONSE) {
|
||||||
// Insert announce into announce table for retransmission
|
// Insert announce into announce table for retransmission
|
||||||
|
|
||||||
if (rate_blocked) {
|
if (rate_blocked) {
|
||||||
debug("Blocking rebroadcast of announce from " + packet.destination_hash().toHex() + " due to excessive announce rate");
|
debug("Blocking rebroadcast of announce from " + packet.destination_hash().toHex() + " due to excessive announce rate");
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (from_local_client(packet)) {
|
if (Transport::from_local_client(packet)) {
|
||||||
// If the announce is from a local client,
|
// If the announce is from a local client,
|
||||||
// it is announced immediately, but only one time.
|
// it is announced immediately, but only one time.
|
||||||
retransmit_timeout = now;
|
retransmit_timeout = now;
|
||||||
retries = Transport::PATHFINDER_R;
|
retries = PATHFINDER_R;
|
||||||
}
|
}
|
||||||
_announce_table[packet.destination_hash] = [
|
AnnounceEntry announce_entry(
|
||||||
now,
|
now,
|
||||||
retransmit_timeout,
|
retransmit_timeout,
|
||||||
retries,
|
retries,
|
||||||
@ -1626,23 +1696,24 @@ using namespace RNS::Utilities;
|
|||||||
local_rebroadcasts,
|
local_rebroadcasts,
|
||||||
block_rebroadcasts,
|
block_rebroadcasts,
|
||||||
attached_interface
|
attached_interface
|
||||||
];
|
);
|
||||||
|
_announce_table.insert({packet.destination_hash(), announce_entry});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// TODO: Check from_local_client once and store result
|
// TODO: Check from_local_client once and store result
|
||||||
else if (from_local_client(packet) && packet.context() == Type::Packet::PATH_RESPONSE) {
|
else if (Transport::from_local_client(packet) && packet.context() == Type::Packet::PATH_RESPONSE) {
|
||||||
// If this is a path response from a local client,
|
// If this is a path response from a local client,
|
||||||
// check if any external interfaces have pending
|
// check if any external interfaces have pending
|
||||||
// path requests.
|
// path requests.
|
||||||
//pif packet.destination_hash in Transport.pending_local_path_requests:
|
//p if packet.destination_hash in Transport.pending_local_path_requests:
|
||||||
auto iter = pending_local_path_requests.find(packet.destination_hash());
|
auto iter = _pending_local_path_requests.find(packet.destination_hash());
|
||||||
if (iter != _destination_table.end()) {
|
if (iter != _pending_local_path_requests.end()) {
|
||||||
DestinationEntry destination_entry = (*iter).second;
|
//p desiring_interface = Transport.pending_local_path_requests.pop(packet.destination_hash)
|
||||||
desiring_interface = _pending_local_path_requests.pop(packet.destination_hash());
|
//const Interface& desiring_interface = (*iter).second;
|
||||||
retransmit_timeout = now;
|
retransmit_timeout = now;
|
||||||
retries = Transport::PATHFINDER_R;
|
retries = PATHFINDER_R;
|
||||||
|
|
||||||
Transport.announce_table[packet.destination_hash] = [
|
AnnounceEntry announce_entry(
|
||||||
now,
|
now,
|
||||||
retransmit_timeout,
|
retransmit_timeout,
|
||||||
retries,
|
retries,
|
||||||
@ -1652,50 +1723,53 @@ using namespace RNS::Utilities;
|
|||||||
local_rebroadcasts,
|
local_rebroadcasts,
|
||||||
block_rebroadcasts,
|
block_rebroadcasts,
|
||||||
attached_interface
|
attached_interface
|
||||||
];
|
);
|
||||||
|
_announce_table.insert({packet.destination_hash(), announce_entry});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// If we have any local clients connected, we re-
|
// If we have any local clients connected, we re-
|
||||||
// transmit the announce to them immediately
|
// transmit the announce to them immediately
|
||||||
if (_local_client_interfaces.size() > 0) {
|
if (_local_client_interfaces.size() > 0) {
|
||||||
announce_identity = Identity::recall(packet.destination_hash());
|
Identity announce_identity(Identity::recall(packet.destination_hash()));
|
||||||
announce_destination = Destination(announce_identity, Destination.OUT, Destination.SINGLE, "unknown", "unknown");
|
Destination announce_destination(announce_identity, Type::Destination::OUT, Type::Destination::SINGLE, "unknown", "unknown");
|
||||||
announce_destination.hash(packet.destination_hash());
|
announce_destination.hash(packet.destination_hash());
|
||||||
announce_destination.hexhash = announce_destination.hash().toHex();
|
//announce_destination.hexhash(announce_destination.hash().toHex());
|
||||||
announce_context = {Type::NONE};
|
Type::Packet::context_types announce_context = Type::Packet::CONTEXT_NONE;
|
||||||
announce_data = packet.data();
|
Bytes announce_data = packet.data();
|
||||||
|
|
||||||
// TODO: Shouldn't the context be PATH_RESPONSE in the first case here?
|
// TODO: Shouldn't the context be PATH_RESPONSE in the first case here?
|
||||||
if (from_local_client(packet) && packet.context() == Packet.PATH_RESPONSE) {
|
if (Transport::from_local_client(packet) && packet.context() == Type::Packet::PATH_RESPONSE) {
|
||||||
for (auto& local_interface : _local_client_interfaces) {
|
for (const Interface& local_interface : _local_client_interfaces) {
|
||||||
if packet.receiving_interface() != local_interface) {
|
if (packet.receiving_interface() != local_interface) {
|
||||||
Packet new_announce(
|
Packet new_announce(
|
||||||
announce_destination,
|
announce_destination,
|
||||||
|
local_interface,
|
||||||
announce_data,
|
announce_data,
|
||||||
Type::Packet::ANNOUNCE,
|
Type::Packet::ANNOUNCE,
|
||||||
context = announce_context,
|
announce_context,
|
||||||
header_type = RNS.Packet.HEADER_2,
|
Type::Transport::TRANSPORT,
|
||||||
transport_type = Transport.TRANSPORT,
|
Type::Packet::HEADER_2,
|
||||||
transport_id = Transport.identity.hash,
|
_identity.hash()
|
||||||
attached_interface = local_interface
|
|
||||||
);
|
);
|
||||||
|
|
||||||
new_announce.hops(packet.hops);
|
new_announce.hops(packet.hops());
|
||||||
new_announce.send();
|
new_announce.send();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
for (auto& local_interface : _local_client_interfaces) {
|
for (const Interface& local_interface : _local_client_interfaces) {
|
||||||
if (packet.receiving_interface() != local_interface) {
|
if (packet.receiving_interface() != local_interface) {
|
||||||
Packet new_announce(
|
Packet new_announce(
|
||||||
announce_destination,
|
announce_destination,
|
||||||
|
local_interface,
|
||||||
announce_data,
|
announce_data,
|
||||||
Type::Packet::ANNOUNCE,
|
Type::Packet::ANNOUNCE,
|
||||||
context = announce_context,
|
announce_context,
|
||||||
header_type = RNS.Packet.HEADER_2,
|
Type::Transport::TRANSPORT,
|
||||||
transport_type = Transport.TRANSPORT,
|
Type::Packet::HEADER_2,
|
||||||
transport_id = Transport.identity.hash,
|
_identity.hash()
|
||||||
attached_interface = local_interface
|
|
||||||
);
|
);
|
||||||
|
|
||||||
new_announce.hops(packet.hops());
|
new_announce.hops(packet.hops());
|
||||||
@ -1710,28 +1784,26 @@ using namespace RNS::Utilities;
|
|||||||
// interface immediately
|
// interface immediately
|
||||||
auto iter = _discovery_path_requests.find(packet.destination_hash());
|
auto iter = _discovery_path_requests.find(packet.destination_hash());
|
||||||
if (iter != _discovery_path_requests.end()) {
|
if (iter != _discovery_path_requests.end()) {
|
||||||
PathRequestEntry pr_entry = (*iter).second;
|
PathRequestEntry& pr_entry = (*iter).second;
|
||||||
attached_interface = pr_entry._requesting_interface;
|
attached_interface = pr_entry._requesting_interface;
|
||||||
|
|
||||||
interface_str = " on " + attached_interface.toString();
|
debug("Got matching announce, answering waiting discovery path request for " + packet.destination_hash().toHex() + " on " + attached_interface.toString());
|
||||||
|
Identity announce_identity(Identity::recall(packet.destination_hash()));
|
||||||
debug("Got matching announce, answering waiting discovery path request for " + packet.destination_hash().toHex() + interface_str);
|
Destination announce_destination(announce_identity, Type::Destination::OUT, Type::Destination::SINGLE, "unknown", "unknown");
|
||||||
announce_identity = Identity::recall(packet.destination_hash());
|
|
||||||
Destination announce_destination(announce_identity, RNS.Destination.OUT, RNS.Destination.SINGLE, "unknown", "unknown");
|
|
||||||
announce_destination.hash(packet.destination_hash());
|
announce_destination.hash(packet.destination_hash());
|
||||||
announce_destination.hexhash = announce_destination.hash().toHex();
|
//announce_destination.hexhash(announce_destination.hash().toHex());
|
||||||
announce_context = {Type::NONE};
|
Type::Packet::context_types announce_context = Type::Packet::CONTEXT_NONE;
|
||||||
announce_data = packet.data();
|
Bytes announce_data = packet.data();
|
||||||
|
|
||||||
Packet new_announce(
|
Packet new_announce(
|
||||||
announce_destination,
|
announce_destination,
|
||||||
|
attached_interface,
|
||||||
announce_data,
|
announce_data,
|
||||||
Type::Packet::ANNOUNCE,
|
Type::Packet::ANNOUNCE,
|
||||||
context = Type::Packet::PATH_RESPONSE,
|
Type::Packet::PATH_RESPONSE,
|
||||||
header_type = Type::Packet::HEADER_2,
|
Type::Transport::TRANSPORT,
|
||||||
transport_type = Type::Transport::TRANSPORT,
|
Type::Packet::HEADER_2,
|
||||||
transport_id = _identity.hash(),
|
_identity.hash()
|
||||||
attached_interface = attached_interface
|
|
||||||
);
|
);
|
||||||
|
|
||||||
new_announce.hops(packet.hops());
|
new_announce.hops(packet.hops());
|
||||||
@ -1744,59 +1816,62 @@ using namespace RNS::Utilities;
|
|||||||
announce_hops,
|
announce_hops,
|
||||||
expires,
|
expires,
|
||||||
random_blobs,
|
random_blobs,
|
||||||
packet.receiving_interface(),
|
//packet.receiving_interface(),
|
||||||
|
const_cast<Interface&>(packet.receiving_interface()),
|
||||||
packet
|
packet
|
||||||
);
|
);
|
||||||
_destination_table.insert({packet.destination_hash(), destination_table_entry});
|
_destination_table.insert({packet.destination_hash(), destination_table_entry});
|
||||||
|
|
||||||
debug("Destination " + packet.destination_hash().toHex() + " is now " + std::to_string(announce_hops) + " hops away via " + received_from.toHex() + " on " + packet.receiving_interface().toString());
|
debug("Destination " + packet.destination_hash().toHex() + " is now " + std::to_string(announce_hops) + " hops away via " + received_from.toHex() + " on " + packet.receiving_interface().toString());
|
||||||
|
|
||||||
|
/*
|
||||||
// If the receiving interface is a tunnel, we add the
|
// If the receiving interface is a tunnel, we add the
|
||||||
// announce to the tunnels table
|
// announce to the tunnels table
|
||||||
if (packet.receiving_interface().tunnel_id()) {
|
if (packet.receiving_interface().tunnel_id()) {
|
||||||
tunnel_entry = Transport.tunnels[packet.receiving_interface.tunnel_id];
|
tunnel_entry = Transport.tunnels[packet.receiving_interface.tunnel_id];
|
||||||
paths = tunnel_entry[2]
|
paths = tunnel_entry[2];
|
||||||
paths[packet.destination_hash] = destination_table_entry
|
paths[packet.destination_hash] = destination_table_entry;
|
||||||
expires = OS::time() + Transport::DESTINATION_TIMEOUT;
|
expires = OS::time() + Transport::DESTINATION_TIMEOUT;
|
||||||
tunnel_entry[3] = expires
|
tunnel_entry[3] = expires;
|
||||||
debug("Path to " + packet.destination_hash().toHex() + " associated with tunnel " + packet.receiving_interface().tunnel_id().toHex());
|
debug("Path to " + packet.destination_hash().toHex() + " associated with tunnel " + packet.receiving_interface().tunnel_id().toHex());
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
// Call externally registered callbacks from apps
|
// Call externally registered callbacks from apps
|
||||||
// wanting to know when an announce arrives
|
// wanting to know when an announce arrives
|
||||||
if (packet.context() != Type::Packet::PATH_RESPONSE) {
|
if (packet.context() != Type::Packet::PATH_RESPONSE) {
|
||||||
for (auto& handler : Transport.announce_handlers) {
|
for (auto& handler : _announce_handlers) {
|
||||||
try {
|
try {
|
||||||
// Check that the announced destination matches
|
// Check that the announced destination matches
|
||||||
// the handlers aspect filter
|
// the handlers aspect filter
|
||||||
execute_callback = false;
|
bool execute_callback = false;
|
||||||
announce_identity = Identity::recall(packet.destination_hash());
|
Identity announce_identity(Identity::recall(packet.destination_hash()));
|
||||||
if (handler.aspect_filter == None) {
|
if (handler->aspect_filter().empty()) {
|
||||||
// If the handlers aspect filter is set to
|
// If the handlers aspect filter is set to
|
||||||
// None, we execute the callback in all cases
|
// None, we execute the callback in all cases
|
||||||
execute_callback = true;
|
execute_callback = true;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
handler_expected_hash = RNS.Destination.hash_from_name_and_identity(handler.aspect_filter, announce_identity)
|
Bytes handler_expected_hash = Destination::hash_from_name_and_identity(handler->aspect_filter().c_str(), announce_identity);
|
||||||
if (packet.destination_hash() == handler_expected_hash() ) {
|
if (packet.destination_hash() == handler_expected_hash) {
|
||||||
execute_callback = true;
|
execute_callback = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (execute_callback) {
|
if (execute_callback) {
|
||||||
handler.received_announce(
|
handler->received_announce(
|
||||||
destination_hash=packet.destination_hash(),
|
packet.destination_hash(),
|
||||||
announced_identity=announce_identity,
|
announce_identity,
|
||||||
app_data=Identity::recall_app_data(packet.destination_hash())
|
Identity::recall_app_data(packet.destination_hash())
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (std::exception& e) {
|
catch (std::exception& e) {
|
||||||
error("Error while processing external announce callback.");
|
error("Error while processing external announce callback.");
|
||||||
error("The contained exception was: " + e.what();
|
error("The contained exception was: " + std::string(e.what()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
extreme("Transport::inbound: Packet is announce for local destination, not processing");
|
extreme("Transport::inbound: Packet is announce for local destination, not processing");
|
||||||
@ -1811,12 +1886,23 @@ using namespace RNS::Utilities;
|
|||||||
else if (packet.packet_type() == Type::Packet::LINKREQUEST) {
|
else if (packet.packet_type() == Type::Packet::LINKREQUEST) {
|
||||||
extreme("Transport::inbound: Packet is LINKREQUEST");
|
extreme("Transport::inbound: Packet is LINKREQUEST");
|
||||||
if (!packet.transport_id() || packet.transport_id() == _identity.hash()) {
|
if (!packet.transport_id() || packet.transport_id() == _identity.hash()) {
|
||||||
|
#if defined(DESTINATIONS_SET)
|
||||||
for (auto& destination : _destinations) {
|
for (auto& destination : _destinations) {
|
||||||
if (destination.hash() == packet.destination_hash() && destination.type() == packet.destination_type()) {
|
if (destination.hash() == packet.destination_hash() && destination.type() == packet.destination_type()) {
|
||||||
|
#elif defined(DESTINATIONS_MAP)
|
||||||
|
auto iter = _destinations.find(packet.destination_hash());
|
||||||
|
if (iter != _destinations.end()) {
|
||||||
|
auto& destination = (*iter).second;
|
||||||
|
if (destination.type() == packet.destination_type()) {
|
||||||
|
#endif
|
||||||
packet.destination(destination);
|
packet.destination(destination);
|
||||||
// CBA iterator over std::set is always const so need to make temporarily mutable
|
// CBA iterator over std::set is always const so need to make temporarily mutable
|
||||||
//destination.receive(packet);
|
//destination.receive(packet);
|
||||||
|
#if defined(DESTINATIONS_SET)
|
||||||
const_cast<Destination&>(destination).receive(packet);
|
const_cast<Destination&>(destination).receive(packet);
|
||||||
|
#else
|
||||||
|
destination.receive(packet);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1834,10 +1920,21 @@ using namespace RNS::Utilities;
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
#if defined(DESTINATIONS_SET)
|
||||||
for (auto& destination : _destinations) {
|
for (auto& destination : _destinations) {
|
||||||
if (destination.hash() == packet.destination_hash() && destination.type() == packet.destination_type()) {
|
if (destination.hash() == packet.destination_hash() && destination.type() == packet.destination_type()) {
|
||||||
|
#elif defined(DESTINATIONS_MAP)
|
||||||
|
auto iter = _destinations.find(packet.destination_hash());
|
||||||
|
if (iter != _destinations.end()) {
|
||||||
|
auto& destination = (*iter).second;
|
||||||
|
if (destination.type() == packet.destination_type()) {
|
||||||
|
#endif
|
||||||
packet.destination(destination);
|
packet.destination(destination);
|
||||||
|
#if defined(DESTINATIONS_SET)
|
||||||
const_cast<Destination&>(destination).receive(packet);
|
const_cast<Destination&>(destination).receive(packet);
|
||||||
|
#else
|
||||||
|
destination.receive(packet);
|
||||||
|
#endif
|
||||||
|
|
||||||
if (destination.proof_strategy() == Type::Destination::PROVE_ALL) {
|
if (destination.proof_strategy() == Type::Destination::PROVE_ALL) {
|
||||||
packet.prove();
|
packet.prove();
|
||||||
@ -2057,39 +2154,71 @@ using namespace RNS::Utilities;
|
|||||||
|
|
||||||
/*static*/ void Transport::register_interface(Interface& interface) {
|
/*static*/ void Transport::register_interface(Interface& interface) {
|
||||||
extreme("Transport: Registering interface " + interface.toString());
|
extreme("Transport: Registering interface " + interface.toString());
|
||||||
|
#if defined(INTERFACES_SET)
|
||||||
|
_interfaces.insert(interface);
|
||||||
|
#elif defined(INTERFACES_LIST)
|
||||||
_interfaces.push_back(interface);
|
_interfaces.push_back(interface);
|
||||||
extreme("Transport: Listing all registered interfaces...");
|
#elif defined(INTERFACES_MAP)
|
||||||
for (Interface& found_interface : _interfaces) {
|
_interfaces.insert({interface.get_hash(), interface});
|
||||||
extreme("Transport: Found interface " + found_interface.toString());
|
#endif
|
||||||
}
|
|
||||||
// CBA TODO set or add transport as listener on interface to receive incoming packets
|
// CBA TODO set or add transport as listener on interface to receive incoming packets
|
||||||
}
|
}
|
||||||
|
|
||||||
/*static*/ void Transport::deregister_interface(const Interface& interface) {
|
/*static*/ void Transport::deregister_interface(const Interface& interface) {
|
||||||
extreme("Transport: Deregistering interface " + interface.toString());
|
extreme("Transport: Deregistering interface " + interface.toString());
|
||||||
//if (_interfaces.find(interface) != _interfaces.end()) {
|
#if defined(INTERFACES_SET)
|
||||||
// _interfaces.erase(interface);
|
//for (auto iter = _interfaces.begin(); iter != _interfaces.end(); ++iter) {
|
||||||
|
// if ((*iter).get() == interface) {
|
||||||
|
// _interfaces.erase(iter);
|
||||||
|
// extreme("Transport::deregister_interface: Found and removed interface " + (*iter).get().toString());
|
||||||
|
// break;
|
||||||
|
// }
|
||||||
//}
|
//}
|
||||||
|
//auto iter = _interfaces.find(interface);
|
||||||
|
auto iter = _interfaces.find(const_cast<Interface&>(interface));
|
||||||
|
if (iter != _interfaces.end()) {
|
||||||
|
_interfaces.erase(iter);
|
||||||
|
extreme("Transport::deregister_interface: Found and removed interface " + (*iter).get().toString());
|
||||||
|
}
|
||||||
|
#elif defined(INTERFACES_LIST)
|
||||||
for (auto iter = _interfaces.begin(); iter != _interfaces.end(); ++iter) {
|
for (auto iter = _interfaces.begin(); iter != _interfaces.end(); ++iter) {
|
||||||
if ((*iter).get() == interface) {
|
if ((*iter).get() == interface) {
|
||||||
_interfaces.erase(iter);
|
_interfaces.erase(iter);
|
||||||
|
extreme("Transport::deregister_interface: Found and removed interface " + (*iter).get().toString());
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#elif defined(INTERFACES_MAP)
|
||||||
|
auto iter = _interfaces.find(interface.get_hash());
|
||||||
|
if (iter != _interfaces.end()) {
|
||||||
|
extreme("Transport::deregister_interface: Found and removing interface " + (*iter).second.toString());
|
||||||
|
_interfaces.erase(iter);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/*static*/ void Transport::register_destination(Destination& destination) {
|
/*static*/ void Transport::register_destination(Destination& destination) {
|
||||||
extreme("Transport: Registering destination " + destination.toString());
|
extreme("Transport: Registering destination " + destination.toString());
|
||||||
destination.mtu(Type::Reticulum::MTU);
|
destination.mtu(Type::Reticulum::MTU);
|
||||||
if (destination.direction() == Type::Destination::IN) {
|
if (destination.direction() == Type::Destination::IN) {
|
||||||
|
#if defined(DESTINATIONS_SET)
|
||||||
for (auto& registered_destination : _destinations) {
|
for (auto& registered_destination : _destinations) {
|
||||||
if (destination.hash() == registered_destination.hash()) {
|
if (destination.hash() == registered_destination.hash()) {
|
||||||
//raise KeyError("Attempt to register an already registered destination.")
|
//raise KeyError("Attempt to register an already registered destination.")
|
||||||
throw std::runtime_error("Attempt to register an already registered destination.");
|
throw std::runtime_error("Attempt to register an already registered destination.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_destinations.insert(destination);
|
_destinations.insert(destination);
|
||||||
|
#elif defined(DESTINATIONS_MAP)
|
||||||
|
auto iter = _destinations.find(destination.hash());
|
||||||
|
if (iter != _destinations.end()) {
|
||||||
|
//raise KeyError("Attempt to register an already registered destination.")
|
||||||
|
throw std::runtime_error("Attempt to register an already registered destination.");
|
||||||
|
}
|
||||||
|
|
||||||
|
_destinations.insert({destination.hash(), destination});
|
||||||
|
#endif
|
||||||
|
|
||||||
if (_owner.is_connected_to_shared_instance()) {
|
if (_owner.is_connected_to_shared_instance()) {
|
||||||
if (destination.type() == Type::Destination::SINGLE) {
|
if (destination.type() == Type::Destination::SINGLE) {
|
||||||
@ -2101,9 +2230,16 @@ using namespace RNS::Utilities;
|
|||||||
|
|
||||||
/*static*/ void Transport::deregister_destination(const Destination& destination) {
|
/*static*/ void Transport::deregister_destination(const Destination& destination) {
|
||||||
extreme("Transport: Deregistering destination " + destination.toString());
|
extreme("Transport: Deregistering destination " + destination.toString());
|
||||||
|
#if defined(DESTINATIONS_SET)
|
||||||
if (_destinations.find(destination) != _destinations.end()) {
|
if (_destinations.find(destination) != _destinations.end()) {
|
||||||
_destinations.erase(destination);
|
_destinations.erase(destination);
|
||||||
}
|
}
|
||||||
|
#elif defined(DESTINATIONS_MAP)
|
||||||
|
auto iter = _destinations.find(destination.hash());
|
||||||
|
if (iter != _destinations.end()) {
|
||||||
|
_destinations.erase(iter);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/*static*/ void Transport::register_link(const Link& link) {
|
/*static*/ void Transport::register_link(const Link& link) {
|
||||||
@ -2141,10 +2277,8 @@ Registers an announce handler.
|
|||||||
:param handler: Must be an object with an *aspect_filter* attribute and a *received_announce(destination_hash, announced_identity, app_data)* callable. See the :ref:`Announce Example<example-announce>` for more info.
|
:param handler: Must be an object with an *aspect_filter* attribute and a *received_announce(destination_hash, announced_identity, app_data)* callable. See the :ref:`Announce Example<example-announce>` for more info.
|
||||||
*/
|
*/
|
||||||
/*static*/ void Transport::register_announce_handler(HAnnounceHandler handler) {
|
/*static*/ void Transport::register_announce_handler(HAnnounceHandler handler) {
|
||||||
extreme("Transport: Transport::register_announce_handler()");
|
extreme("Transport: Registering announce handler " + handler->aspect_filter());
|
||||||
//if hasattr(handler, "received_announce") and callable(handler.received_announce):
|
_announce_handlers.insert(handler);
|
||||||
//if hasattr(handler, "aspect_filter"):
|
|
||||||
_announce_handlers.insert(handler);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -2153,18 +2287,32 @@ Deregisters an announce handler.
|
|||||||
:param handler: The announce handler to be deregistered.
|
:param handler: The announce handler to be deregistered.
|
||||||
*/
|
*/
|
||||||
/*static*/ void Transport::deregister_announce_handler(HAnnounceHandler handler) {
|
/*static*/ void Transport::deregister_announce_handler(HAnnounceHandler handler) {
|
||||||
extreme("Transport: Transport::deregister_announce_handler()");
|
extreme("Transport: Deregistering announce handler " + handler->aspect_filter());
|
||||||
if (_announce_handlers.find(handler) != _announce_handlers.end()) {
|
if (_announce_handlers.find(handler) != _announce_handlers.end()) {
|
||||||
_announce_handlers.erase(handler);
|
_announce_handlers.erase(handler);
|
||||||
|
extreme("Transport::deregister_announce_handler: Found and removed handler" + handler->aspect_filter());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*static*/ Interface Transport::find_interface_from_hash(const Bytes& interface_hash) {
|
/*static*/ Interface Transport::find_interface_from_hash(const Bytes& interface_hash) {
|
||||||
|
#if defined(INTERFACES_SET)
|
||||||
for (const Interface& interface : _interfaces) {
|
for (const Interface& interface : _interfaces) {
|
||||||
if (interface.get_hash() == interface_hash) {
|
if (interface.get_hash() == interface_hash) {
|
||||||
return interface;
|
return interface;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#elif defined(INTERFACES_LIST)
|
||||||
|
for (Interface& interface : _interfaces) {
|
||||||
|
if (interface.get_hash() == interface_hash) {
|
||||||
|
return interface;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#elif defined(INTERFACES_MAP)
|
||||||
|
auto iter = _interfaces.find(interface_hash);
|
||||||
|
if (iter != _interfaces.end()) {
|
||||||
|
return (*iter).second;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
return {Type::NONE};
|
return {Type::NONE};
|
||||||
}
|
}
|
||||||
@ -2299,7 +2447,7 @@ Deregisters an announce handler.
|
|||||||
return destination_entry._hops;
|
return destination_entry._hops;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return Transport::PATHFINDER_M;
|
return PATHFINDER_M;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2479,6 +2627,7 @@ will announce it.
|
|||||||
Transport.pending_local_path_requests[destination_hash] = attached_interface
|
Transport.pending_local_path_requests[destination_hash] = attached_interface
|
||||||
|
|
||||||
//local_destination = next((d for d in Transport.destinations if d.hash == destination_hash), None)
|
//local_destination = next((d for d in Transport.destinations if d.hash == destination_hash), None)
|
||||||
|
#if defined(DESTINATIONS_SET)
|
||||||
Destination local_destination({Type::NONE});
|
Destination local_destination({Type::NONE});
|
||||||
for (auto& destination : _destinations) {
|
for (auto& destination : _destinations) {
|
||||||
if (destination.hash() == destination_hash) {
|
if (destination.hash() == destination_hash) {
|
||||||
@ -2488,11 +2637,15 @@ will announce it.
|
|||||||
}
|
}
|
||||||
//if local_destination != None:
|
//if local_destination != None:
|
||||||
if (local_destination) {
|
if (local_destination) {
|
||||||
|
#elif defined(DESTINATIONS_MAP)
|
||||||
|
auto iter = _destinations.find(destination_hash);
|
||||||
|
if (iter != _destinations.end()) {
|
||||||
|
auto& local_destination = (*iter).second;
|
||||||
|
#endif
|
||||||
local_destination.announce(path_response=True, tag=tag, attached_interface=attached_interface);
|
local_destination.announce(path_response=True, tag=tag, attached_interface=attached_interface);
|
||||||
debug("Answering path request for " + destination_hash.toHex() + interface_str + ", destination is local to this system");
|
debug("Answering path request for " + destination_hash.toHex() + interface_str + ", destination is local to this system");
|
||||||
}
|
}
|
||||||
|
else if ((RNS.Reticulum.transport_enabled() || is_from_local_client) && destination_table.find(destination_hash) != _destination_table.ends()) {
|
||||||
elif (RNS.Reticulum.transport_enabled() or is_from_local_client) and (destination_hash in Transport.destination_table):
|
|
||||||
packet = Transport.destination_table[destination_hash][6]
|
packet = Transport.destination_table[destination_hash][6]
|
||||||
next_hop = Transport.destination_table[destination_hash][1]
|
next_hop = Transport.destination_table[destination_hash][1]
|
||||||
received_from = Transport.destination_table[destination_hash][5]
|
received_from = Transport.destination_table[destination_hash][5]
|
||||||
@ -2892,3 +3045,20 @@ will announce it.
|
|||||||
persist_data();
|
persist_data();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*static*/ Destination Transport::find_destination_from_hash(const Bytes& destination_hash) {
|
||||||
|
#if defined(DESTINATIONS_SET)
|
||||||
|
for (const Destination& destination : _destinations) {
|
||||||
|
if (destination.get_hash() == destination_hash) {
|
||||||
|
return destination;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#elif defined(DESTINATIONS_MAP)
|
||||||
|
auto iter = _destinations.find(destination_hash);
|
||||||
|
if (iter != _destinations.end()) {
|
||||||
|
return (*iter).second;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return {Type::NONE};
|
||||||
|
}
|
||||||
|
126
src/Transport.h
126
src/Transport.h
@ -11,6 +11,13 @@
|
|||||||
#include <functional>
|
#include <functional>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
|
//#define INTERFACES_SET
|
||||||
|
//#define INTERFACES_LIST
|
||||||
|
#define INTERFACES_MAP
|
||||||
|
|
||||||
|
//#define DESTINATIONS_SET
|
||||||
|
#define DESTINATIONS_MAP
|
||||||
|
|
||||||
namespace RNS {
|
namespace RNS {
|
||||||
|
|
||||||
class Reticulum;
|
class Reticulum;
|
||||||
@ -23,10 +30,18 @@ namespace RNS {
|
|||||||
|
|
||||||
class AnnounceHandler {
|
class AnnounceHandler {
|
||||||
public:
|
public:
|
||||||
AnnounceHandler(const std::string& aspect_filter) {
|
// The initialisation method takes the optional
|
||||||
_aspect_filter = aspect_filter;
|
// aspect_filter argument. If aspect_filter is set to
|
||||||
}
|
// None, all announces will be passed to the instance.
|
||||||
|
// If only some announces are wanted, it can be set to
|
||||||
|
// an aspect string.
|
||||||
|
AnnounceHandler(const char* aspect_filter) { _aspect_filter = aspect_filter; }
|
||||||
|
// This method will be called by Reticulums Transport
|
||||||
|
// system when an announce arrives that matches the
|
||||||
|
// configured aspect filter. Filters must be specific,
|
||||||
|
// and cannot use wildcards.
|
||||||
virtual void received_announce(const Bytes& destination_hash, const Identity& announced_identity, const Bytes& app_data) = 0;
|
virtual void received_announce(const Bytes& destination_hash, const Identity& announced_identity, const Bytes& app_data) = 0;
|
||||||
|
std::string& aspect_filter() { return _aspect_filter; }
|
||||||
private:
|
private:
|
||||||
std::string _aspect_filter;
|
std::string _aspect_filter;
|
||||||
};
|
};
|
||||||
@ -39,9 +54,11 @@ namespace RNS {
|
|||||||
class Transport {
|
class Transport {
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
// CBA TODO Analyze safety of using Inrerface references here
|
||||||
|
// CBA TODO Analyze safety of using Packet references here
|
||||||
class DestinationEntry {
|
class DestinationEntry {
|
||||||
public:
|
public:
|
||||||
DestinationEntry(uint64_t time, Bytes received_from, uint8_t announce_hops, uint64_t expires, std::set<Bytes> random_blobs, Interface& receiving_interface, const Packet& packet) :
|
DestinationEntry(uint64_t time, const Bytes& received_from, uint8_t announce_hops, uint64_t expires, const std::set<Bytes>& random_blobs, Interface& receiving_interface, const Packet& packet) :
|
||||||
_timestamp(time),
|
_timestamp(time),
|
||||||
_received_from(received_from),
|
_received_from(received_from),
|
||||||
_hops(announce_hops),
|
_hops(announce_hops),
|
||||||
@ -61,9 +78,11 @@ namespace RNS {
|
|||||||
const Packet& _packet;
|
const Packet& _packet;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// CBA TODO Analyze safety of using Inrerface references here
|
||||||
|
// CBA TODO Analyze safety of using Packet references here
|
||||||
class AnnounceEntry {
|
class AnnounceEntry {
|
||||||
public:
|
public:
|
||||||
AnnounceEntry(uint64_t timestamp, uint16_t retransmit_timeout, uint8_t retries, Bytes received_from, uint8_t hops, const Packet& packet, uint8_t local_rebroadcasts, bool block_rebroadcasts, const Interface& attached_interface) :
|
AnnounceEntry(uint64_t timestamp, uint16_t retransmit_timeout, uint8_t retries, const Bytes& received_from, uint8_t hops, const Packet& packet, uint8_t local_rebroadcasts, bool block_rebroadcasts, const Interface& attached_interface) :
|
||||||
_timestamp(timestamp),
|
_timestamp(timestamp),
|
||||||
_retransmit_timeout(retransmit_timeout),
|
_retransmit_timeout(retransmit_timeout),
|
||||||
_retries(retries),
|
_retries(retries),
|
||||||
@ -87,9 +106,10 @@ namespace RNS {
|
|||||||
const Interface& _attached_interface;
|
const Interface& _attached_interface;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// CBA TODO Analyze safety of using Inrerface references here
|
||||||
class LinkEntry {
|
class LinkEntry {
|
||||||
public:
|
public:
|
||||||
LinkEntry(uint64_t timestamp, const Bytes& next_hop, const Interface& outbound_interface, uint8_t remaining_hops, const Interface& receiving_interface, uint8_t hops, const Bytes& destination_hash, bool validated, uint64_t proof_timeout) :
|
LinkEntry(uint64_t timestamp, const Bytes& next_hop, const Interface& outbound_interface, uint8_t remaining_hops, const Interface& receiving_interface, uint8_t hops, const Bytes& destination_hash, bool validated, uint64_t proof_timeout) :
|
||||||
_timestamp(timestamp),
|
_timestamp(timestamp),
|
||||||
_next_hop(next_hop),
|
_next_hop(next_hop),
|
||||||
_outbound_interface(outbound_interface),
|
_outbound_interface(outbound_interface),
|
||||||
@ -113,9 +133,10 @@ namespace RNS {
|
|||||||
uint64_t _proof_timeout = 0;
|
uint64_t _proof_timeout = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// CBA TODO Analyze safety of using Inrerface references here
|
||||||
class ReverseEntry {
|
class ReverseEntry {
|
||||||
public:
|
public:
|
||||||
ReverseEntry(const Interface& receiving_interface, const Interface& outbound_interface, uint64_t timestamp) :
|
ReverseEntry(const Interface& receiving_interface, const Interface& outbound_interface, uint64_t timestamp) :
|
||||||
_receiving_interface(receiving_interface),
|
_receiving_interface(receiving_interface),
|
||||||
_outbound_interface(outbound_interface),
|
_outbound_interface(outbound_interface),
|
||||||
_timestamp(timestamp)
|
_timestamp(timestamp)
|
||||||
@ -127,50 +148,20 @@ namespace RNS {
|
|||||||
uint64_t _timestamp = 0;
|
uint64_t _timestamp = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
public:
|
// CBA TODO Analyze safety of using Inrerface references here
|
||||||
// Constants
|
class PathRequestEntry {
|
||||||
/*
|
public:
|
||||||
enum types {
|
PathRequestEntry(const Bytes& destination_hash, uint64_t timeout, const Interface& requesting_interface) :
|
||||||
BROADCAST = 0x00,
|
_destination_hash(destination_hash),
|
||||||
TRANSPORT = 0x01,
|
_timeout(timeout),
|
||||||
RELAY = 0x02,
|
_requesting_interface(requesting_interface)
|
||||||
TUNNEL = 0x03,
|
{
|
||||||
NONE = 0xFF,
|
}
|
||||||
|
public:
|
||||||
|
Bytes _destination_hash;
|
||||||
|
uint64_t _timeout = 0;
|
||||||
|
const Interface& _requesting_interface;
|
||||||
};
|
};
|
||||||
*/
|
|
||||||
|
|
||||||
enum reachabilities {
|
|
||||||
REACHABILITY_UNREACHABLE = 0x00,
|
|
||||||
REACHABILITY_DIRECT = 0x01,
|
|
||||||
REACHABILITY_TRANSPORT = 0x02,
|
|
||||||
};
|
|
||||||
|
|
||||||
static constexpr const char* APP_NAME = "rnstransport";
|
|
||||||
|
|
||||||
static const uint8_t PATHFINDER_M = 128; // Max hops
|
|
||||||
// Maximum amount of hops that Reticulum will transport a packet.
|
|
||||||
|
|
||||||
static const uint8_t PATHFINDER_R = 1; // Retransmit retries
|
|
||||||
static const uint8_t PATHFINDER_G = 5; // Retry grace period
|
|
||||||
static constexpr const float PATHFINDER_RW = 0.5; // Random window for announce rebroadcast
|
|
||||||
static const uint32_t PATHFINDER_E = 60*60*24*7; // Path expiration of one week
|
|
||||||
static const uint32_t AP_PATH_TIME = 60*60*24; // Path expiration of one day for Access Point paths
|
|
||||||
static const uint32_t ROAMING_PATH_TIME = 60*60*6; // Path expiration of 6 hours for Roaming paths
|
|
||||||
|
|
||||||
// TODO: Calculate an optimal number for this in
|
|
||||||
// various situations
|
|
||||||
static const uint8_t LOCAL_REBROADCASTS_MAX = 2; // How many local rebroadcasts of an announce is allowed
|
|
||||||
|
|
||||||
static const uint8_t PATH_REQUEST_TIMEOUT = 15; // Default timuout for client path requests in seconds
|
|
||||||
static constexpr const float PATH_REQUEST_GRACE = 0.35; // Grace time before a path announcement is made, allows directly reachable peers to respond first
|
|
||||||
static const uint8_t PATH_REQUEST_RW = 2; // Path request random window
|
|
||||||
static const uint8_t PATH_REQUEST_MI = 5; // Minimum interval in seconds for automated path requests
|
|
||||||
|
|
||||||
static constexpr const float LINK_TIMEOUT = Type::Link::STALE_TIME * 1.25;
|
|
||||||
static const uint16_t REVERSE_TIMEOUT = 30*60; // Reverse table entries are removed after 30 minutes
|
|
||||||
static const uint32_t DESTINATION_TIMEOUT = 60*60*24*7; // Destination table entries are removed if unused for one week
|
|
||||||
static const uint16_t MAX_RECEIPTS = 1024; // Maximum number of receipts to keep track of
|
|
||||||
static const uint8_t MAX_RATE_TIMESTAMPS = 16; // Maximum number of announce timestamps to keep per destination
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static void start(const Reticulum& reticulum_instance);
|
static void start(const Reticulum& reticulum_instance);
|
||||||
@ -223,12 +214,26 @@ namespace RNS {
|
|||||||
static void persist_data();
|
static void persist_data();
|
||||||
static void exit_handler();
|
static void exit_handler();
|
||||||
|
|
||||||
|
static Destination find_destination_from_hash(const Bytes& destination_hash);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// CBA MUST use references to interfaces here in order for virtul overrides for send/receive to work
|
// CBA MUST use references to interfaces here in order for virtul overrides for send/receive to work
|
||||||
|
#if defined(INTERFACES_SET)
|
||||||
|
// set sorted, can use find
|
||||||
//static std::set<std::reference_wrapper<const Interface>, std::less<const Interface>> _interfaces; // All active interfaces
|
//static std::set<std::reference_wrapper<const Interface>, std::less<const Interface>> _interfaces; // All active interfaces
|
||||||
|
static std::set<std::reference_wrapper<Interface>, std::less<Interface>> _interfaces; // All active interfaces
|
||||||
|
#elif defined(INTERFACES_LIST)
|
||||||
|
// list is unsorted, can't use find
|
||||||
static std::list<std::reference_wrapper<Interface>> _interfaces; // All active interfaces
|
static std::list<std::reference_wrapper<Interface>> _interfaces; // All active interfaces
|
||||||
|
#elif defined(INTERFACES_MAP)
|
||||||
|
// map is sorted, can use find
|
||||||
|
static std::map<Bytes, Interface&> _interfaces; // All active interfaces
|
||||||
|
#endif
|
||||||
|
#if defined(DESTINATIONS_SET)
|
||||||
static std::set<Destination> _destinations; // All active destinations
|
static std::set<Destination> _destinations; // All active destinations
|
||||||
//static std::map<Bytes, Destination> _destinations; // All active destinations
|
#elif defined(DESTINATIONS_MAP)
|
||||||
|
static std::map<Bytes, Destination> _destinations; // All active destinations
|
||||||
|
#endif
|
||||||
static std::set<Link> _pending_links; // Links that are being established
|
static std::set<Link> _pending_links; // Links that are being established
|
||||||
static std::set<Link> _active_links; // Links that are active
|
static std::set<Link> _active_links; // Links that are active
|
||||||
static std::set<Bytes> _packet_hashlist; // A list of packet hashes for duplicate detection
|
static std::set<Bytes> _packet_hashlist; // A list of packet hashes for duplicate detection
|
||||||
@ -244,12 +249,12 @@ namespace RNS {
|
|||||||
static std::map<Bytes, LinkEntry> _link_table; // A lookup table containing hops for links
|
static std::map<Bytes, LinkEntry> _link_table; // A lookup table containing hops for links
|
||||||
static std::map<Bytes, AnnounceEntry> _held_announces; // A table containing temporarily held announce-table entries
|
static std::map<Bytes, AnnounceEntry> _held_announces; // A table containing temporarily held announce-table entries
|
||||||
static std::set<HAnnounceHandler> _announce_handlers; // A table storing externally registered announce handlers
|
static std::set<HAnnounceHandler> _announce_handlers; // A table storing externally registered announce handlers
|
||||||
//z_tunnels = {} // A table storing tunnels to other transport instances
|
//z _tunnels = {} // A table storing tunnels to other transport instances
|
||||||
//z_announce_rate_table = {} // A table for keeping track of announce rates
|
//z _announce_rate_table = {} // A table for keeping track of announce rates
|
||||||
static std::set<Bytes> _path_requests; // A table for storing path request timestamps
|
static std::set<Bytes> _path_requests; // A table for storing path request timestamps
|
||||||
|
|
||||||
//z_discovery_path_requests = {} // A table for keeping track of path requests on behalf of other nodes
|
static std::map<Bytes, PathRequestEntry> _discovery_path_requests; // A table for keeping track of path requests on behalf of other nodes
|
||||||
//z_discovery_pr_tags = [] // A table for keeping track of tagged path requests
|
//z _discovery_pr_tags = [] // A table for keeping track of tagged path requests
|
||||||
static uint16_t _max_pr_taXgxs; // Maximum amount of unique path request tags to remember
|
static uint16_t _max_pr_taXgxs; // Maximum amount of unique path request tags to remember
|
||||||
|
|
||||||
// Transport control destinations are used
|
// Transport control destinations are used
|
||||||
@ -260,14 +265,15 @@ namespace RNS {
|
|||||||
// Interfaces for communicating with
|
// Interfaces for communicating with
|
||||||
// local clients connected to a shared
|
// local clients connected to a shared
|
||||||
// Reticulum instance
|
// Reticulum instance
|
||||||
static std::set<Interface> _local_client_interfaces;
|
//static std::set<Interface> _local_client_interfaces;
|
||||||
|
static std::set<std::reference_wrapper<const Interface>, std::less<const Interface>> _local_client_interfaces;
|
||||||
|
|
||||||
//z_local_client_rssi_cache = []
|
static std::map<Bytes, const Interface&> _pending_local_path_requests;
|
||||||
//z_local_client_snr_cache = []
|
|
||||||
|
//z _local_client_rssi_cache = []
|
||||||
|
//z _local_client_snr_cache = []
|
||||||
static uint16_t _LOCAL_CLIENT_CACHE_MAXSIZE;
|
static uint16_t _LOCAL_CLIENT_CACHE_MAXSIZE;
|
||||||
|
|
||||||
std::map<Bytes, Interface> _pending_local_path_requests;
|
|
||||||
|
|
||||||
static uint64_t _start_time;
|
static uint64_t _start_time;
|
||||||
static bool _jobs_locked;
|
static bool _jobs_locked;
|
||||||
static bool _jobs_running;
|
static bool _jobs_running;
|
||||||
|
@ -65,7 +65,7 @@ namespace RNS { namespace Type {
|
|||||||
static const uint16_t HEADER_MINSIZE = 2+1+(TRUNCATED_HASHLENGTH/8)*1; // In bytes
|
static const uint16_t HEADER_MINSIZE = 2+1+(TRUNCATED_HASHLENGTH/8)*1; // In bytes
|
||||||
static const uint16_t HEADER_MAXSIZE = 2+1+(TRUNCATED_HASHLENGTH/8)*2; // In bytes
|
static const uint16_t HEADER_MAXSIZE = 2+1+(TRUNCATED_HASHLENGTH/8)*2; // In bytes
|
||||||
static const uint16_t IFAC_MIN_SIZE = 1;
|
static const uint16_t IFAC_MIN_SIZE = 1;
|
||||||
//zIFAC_SALT = bytes.fromhex("adf54d882c9a9b80771eb4995d702d4a3e733391b2a0f53f416d9f907e55cff8")
|
//z IFAC_SALT = bytes.fromhex("adf54d882c9a9b80771eb4995d702d4a3e733391b2a0f53f416d9f907e55cff8")
|
||||||
|
|
||||||
static const uint16_t MDU = MTU - HEADER_MAXSIZE - IFAC_MIN_SIZE;
|
static const uint16_t MDU = MTU - HEADER_MAXSIZE - IFAC_MIN_SIZE;
|
||||||
|
|
||||||
|
46
src/main.cpp
46
src/main.cpp
@ -115,16 +115,34 @@ public:
|
|||||||
name("(deleted)");
|
name("(deleted)");
|
||||||
}
|
}
|
||||||
virtual void processIncoming(const RNS::Bytes& data) {
|
virtual void processIncoming(const RNS::Bytes& data) {
|
||||||
RNS::head("TestInInterface.processIncoming: data: " + data.toHex(), RNS::LOG_EXTREME);
|
RNS::head("TestInInterface.processIncoming: data: " + data.toHex(), RNS::LOG_INFO);
|
||||||
RNS::Interface::processIncoming(data);
|
RNS::Interface::processIncoming(data);
|
||||||
}
|
}
|
||||||
virtual inline std::string toString() const { return "TestInInterface[" + name() + "]"; }
|
virtual inline std::string toString() const { return "TestInInterface[" + name() + "]"; }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Test AnnounceHandler
|
||||||
|
class ExampleAnnounceHandler : public RNS::AnnounceHandler {
|
||||||
|
public:
|
||||||
|
ExampleAnnounceHandler(const char* aspect_filter) : AnnounceHandler(aspect_filter) {}
|
||||||
|
virtual void received_announce(const RNS::Bytes& destination_hash, const RNS::Identity& announced_identity, const RNS::Bytes& app_data) {
|
||||||
|
RNS::info("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
|
||||||
|
RNS::info("ExampleAnnounceHandler: destination hash: " + destination_hash.toHex());
|
||||||
|
RNS::info("ExampleAnnounceHandler: destination hash: " + destination_hash.toHex());
|
||||||
|
if (app_data) {
|
||||||
|
RNS::info("ExampleAnnounceHandler: app data: " + app_data.toString());
|
||||||
|
}
|
||||||
|
RNS::info("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Test packet receive callback
|
||||||
void onPacket(const RNS::Bytes& data, const RNS::Packet& packet) {
|
void onPacket(const RNS::Bytes& data, const RNS::Packet& packet) {
|
||||||
RNS::head("onPacket: data: " + data.toHex(), RNS::LOG_EXTREME);
|
RNS::info("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
|
||||||
RNS::head("onPacket: data string: \"" + data.toString() + "\"", RNS::LOG_EXTREME);
|
RNS::head("onPacket: data: " + data.toHex(), RNS::LOG_INFO);
|
||||||
|
RNS::head("onPacket: data string: \"" + data.toString() + "\"", RNS::LOG_INFO);
|
||||||
//RNS::head("onPacket: " + packet.debugString(), RNS::LOG_EXTREME);
|
//RNS::head("onPacket: " + packet.debugString(), RNS::LOG_EXTREME);
|
||||||
|
RNS::info("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
|
||||||
}
|
}
|
||||||
|
|
||||||
void setup() {
|
void setup() {
|
||||||
@ -202,11 +220,10 @@ void setup() {
|
|||||||
|
|
||||||
destination.set_proof_strategy(RNS::Type::Destination::PROVE_ALL);
|
destination.set_proof_strategy(RNS::Type::Destination::PROVE_ALL);
|
||||||
|
|
||||||
//zRNS::head("Registering announce handler with Transport...", RNS::LOG_EXTREME);
|
RNS::head("Registering announce handler with Transport...", RNS::LOG_EXTREME);
|
||||||
//zannounce_handler = ExampleAnnounceHandler(
|
RNS::HAnnounceHandler announce_handler(new ExampleAnnounceHandler("example_utilities.announcesample.fruits"));
|
||||||
//z aspect_filter="example_utilities.announcesample.fruits";
|
//ExampleAnnounceHandler announce_handler((const char*)"example_utilities.announcesample.fruits");
|
||||||
//z)
|
RNS::Transport::register_announce_handler(announce_handler);
|
||||||
//zRNS::Transport.register_announce_handler(announce_handler);
|
|
||||||
|
|
||||||
RNS::head("Announcing destination...", RNS::LOG_EXTREME);
|
RNS::head("Announcing destination...", RNS::LOG_EXTREME);
|
||||||
//destination.announce(RNS::bytesFromString(fruits[rand() % 7]));
|
//destination.announce(RNS::bytesFromString(fruits[rand() % 7]));
|
||||||
@ -216,7 +233,7 @@ void setup() {
|
|||||||
destination.announce(RNS::bytesFromString(fruits[rand() % 7]));
|
destination.announce(RNS::bytesFromString(fruits[rand() % 7]));
|
||||||
// 23.9% (+0.8%)
|
// 23.9% (+0.8%)
|
||||||
|
|
||||||
/**/
|
/*
|
||||||
// test data send packet
|
// test data send packet
|
||||||
RNS::head("Creating send packet...", RNS::LOG_EXTREME);
|
RNS::head("Creating send packet...", RNS::LOG_EXTREME);
|
||||||
RNS::Packet send_packet(destination, "The quick brown fox jumps over the lazy dog");
|
RNS::Packet send_packet(destination, "The quick brown fox jumps over the lazy dog");
|
||||||
@ -236,7 +253,16 @@ void setup() {
|
|||||||
|
|
||||||
RNS::head("Spoofing recv packet to destination...", RNS::LOG_EXTREME);
|
RNS::head("Spoofing recv packet to destination...", RNS::LOG_EXTREME);
|
||||||
destination.receive(recv_packet);
|
destination.receive(recv_packet);
|
||||||
/**/
|
*/
|
||||||
|
|
||||||
|
RNS::head("Deregistering announce handler with Transport...", RNS::LOG_EXTREME);
|
||||||
|
RNS::Transport::deregister_announce_handler(announce_handler);
|
||||||
|
|
||||||
|
RNS::head("Deregistering Interface instances with Transport...", RNS::LOG_EXTREME);
|
||||||
|
RNS::Transport::deregister_interface(loopinterface);
|
||||||
|
RNS::Transport::deregister_interface(ininterface);
|
||||||
|
RNS::Transport::deregister_interface(outinterface);
|
||||||
|
//RNS::Transport::deregister_interface(interface);
|
||||||
|
|
||||||
}
|
}
|
||||||
catch (std::exception& e) {
|
catch (std::exception& e) {
|
||||||
|
Loading…
Reference in New Issue
Block a user