Implemented propagation node name configuration and inclusion in announce metadata
This commit is contained in:
parent
704b37dc16
commit
0a5edb2895
4 changed files with 66 additions and 5 deletions
22
LXMF/LXMF.py
22
LXMF/LXMF.py
|
|
@ -147,6 +147,28 @@ def stamp_cost_from_app_data(app_data=None):
|
||||||
# Original announce format
|
# Original announce format
|
||||||
else: return None
|
else: return None
|
||||||
|
|
||||||
|
def pn_name_from_app_data(app_data=None):
|
||||||
|
if app_data == None: return None
|
||||||
|
else:
|
||||||
|
if pn_announce_data_is_valid(app_data):
|
||||||
|
data = msgpack.unpackb(app_data)
|
||||||
|
metadata = data[6]
|
||||||
|
if not PN_META_NAME in metadata: return None
|
||||||
|
else:
|
||||||
|
try: return metadata[PN_META_NAME].decode("utf-8")
|
||||||
|
except: return None
|
||||||
|
|
||||||
|
return None
|
||||||
|
|
||||||
|
def pn_stamp_cost_from_app_data(app_data=None):
|
||||||
|
if app_data == None: return None
|
||||||
|
else:
|
||||||
|
if pn_announce_data_is_valid(app_data):
|
||||||
|
data = msgpack.unpackb(app_data)
|
||||||
|
return data[5][0]
|
||||||
|
else:
|
||||||
|
return None
|
||||||
|
|
||||||
def pn_announce_data_is_valid(data):
|
def pn_announce_data_is_valid(data):
|
||||||
try:
|
try:
|
||||||
if type(data) != bytes: return False
|
if type(data) != bytes: return False
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,7 @@ import LXMF.LXStamper as LXStamper
|
||||||
|
|
||||||
from collections import deque
|
from collections import deque
|
||||||
from .LXMF import APP_NAME
|
from .LXMF import APP_NAME
|
||||||
|
from .LXMF import PN_META_NAME
|
||||||
|
|
||||||
class LXMPeer:
|
class LXMPeer:
|
||||||
OFFER_REQUEST_PATH = "/offer"
|
OFFER_REQUEST_PATH = "/offer"
|
||||||
|
|
@ -110,6 +111,8 @@ class LXMPeer:
|
||||||
else: peer.last_sync_attempt = 0
|
else: peer.last_sync_attempt = 0
|
||||||
if "peering_key" in dictionary: peer.peering_key = dictionary["peering_key"]
|
if "peering_key" in dictionary: peer.peering_key = dictionary["peering_key"]
|
||||||
else: peer.peering_key = None
|
else: peer.peering_key = None
|
||||||
|
if "metadata" in dictionary: peer.metadata = dictionary["metadata"]
|
||||||
|
else: peer.metadata = None
|
||||||
|
|
||||||
hm_count = 0
|
hm_count = 0
|
||||||
for transient_id in dictionary["handled_ids"]:
|
for transient_id in dictionary["handled_ids"]:
|
||||||
|
|
@ -135,6 +138,7 @@ class LXMPeer:
|
||||||
dictionary = {}
|
dictionary = {}
|
||||||
dictionary["peering_timebase"] = self.peering_timebase
|
dictionary["peering_timebase"] = self.peering_timebase
|
||||||
dictionary["alive"] = self.alive
|
dictionary["alive"] = self.alive
|
||||||
|
dictionary["metadata"] = self.metadata
|
||||||
dictionary["last_heard"] = self.last_heard
|
dictionary["last_heard"] = self.last_heard
|
||||||
dictionary["sync_strategy"] = self.sync_strategy
|
dictionary["sync_strategy"] = self.sync_strategy
|
||||||
dictionary["peering_key"] = self.peering_key
|
dictionary["peering_key"] = self.peering_key
|
||||||
|
|
@ -175,6 +179,7 @@ class LXMPeer:
|
||||||
self.sync_strategy = sync_strategy
|
self.sync_strategy = sync_strategy
|
||||||
self.peering_key = None
|
self.peering_key = None
|
||||||
self.peering_cost = None
|
self.peering_cost = None
|
||||||
|
self.metadata = None
|
||||||
|
|
||||||
self.next_sync_attempt = 0
|
self.next_sync_attempt = 0
|
||||||
self.last_sync_attempt = 0
|
self.last_sync_attempt = 0
|
||||||
|
|
@ -616,6 +621,15 @@ class LXMPeer:
|
||||||
self.router.propagation_entries[transient_id][5].remove(self.destination_hash)
|
self.router.propagation_entries[transient_id][5].remove(self.destination_hash)
|
||||||
self._um_counts_synced = False
|
self._um_counts_synced = False
|
||||||
|
|
||||||
|
@property
|
||||||
|
def name(self):
|
||||||
|
if type(self.metadata) != dict: return None
|
||||||
|
else:
|
||||||
|
if not PN_META_NAME in self.metadata: return None
|
||||||
|
else:
|
||||||
|
try: return self.metadata[PN_META_NAME].decode("utf-8")
|
||||||
|
except: return None
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
if self.destination_hash: return RNS.prettyhexrep(self.destination_hash)
|
if self.destination_hash: return RNS.prettyhexrep(self.destination_hash)
|
||||||
else: return "<Unknown>"
|
else: return "<Unknown>"
|
||||||
|
|
@ -15,6 +15,7 @@ import RNS.vendor.umsgpack as msgpack
|
||||||
|
|
||||||
from .LXMF import APP_NAME
|
from .LXMF import APP_NAME
|
||||||
from .LXMF import FIELD_TICKET
|
from .LXMF import FIELD_TICKET
|
||||||
|
from .LXMF import PN_META_NAME
|
||||||
from .LXMF import pn_announce_data_is_valid
|
from .LXMF import pn_announce_data_is_valid
|
||||||
|
|
||||||
from .LXMPeer import LXMPeer
|
from .LXMPeer import LXMPeer
|
||||||
|
|
@ -84,7 +85,7 @@ class LXMRouter:
|
||||||
enforce_ratchets=False, enforce_stamps=False, static_peers = [], max_peers=None,
|
enforce_ratchets=False, enforce_stamps=False, static_peers = [], max_peers=None,
|
||||||
from_static_only=False, sync_strategy=LXMPeer.STRATEGY_PERSISTENT,
|
from_static_only=False, sync_strategy=LXMPeer.STRATEGY_PERSISTENT,
|
||||||
propagation_cost=PROPAGATION_COST, propagation_cost_flexibility=PROPAGATION_COST_FLEX,
|
propagation_cost=PROPAGATION_COST, propagation_cost_flexibility=PROPAGATION_COST_FLEX,
|
||||||
peering_cost=PEERING_COST):
|
peering_cost=PEERING_COST, name=None):
|
||||||
|
|
||||||
random.seed(os.urandom(10))
|
random.seed(os.urandom(10))
|
||||||
|
|
||||||
|
|
@ -105,9 +106,10 @@ class LXMRouter:
|
||||||
self.processing_outbound = False
|
self.processing_outbound = False
|
||||||
self.processing_inbound = False
|
self.processing_inbound = False
|
||||||
self.processing_count = 0
|
self.processing_count = 0
|
||||||
|
self.name = name
|
||||||
|
|
||||||
self.propagation_node = False
|
self.propagation_node = False
|
||||||
self.propagation_node_start_time = None
|
self.propagation_node_start_time = None
|
||||||
|
|
||||||
if storagepath == None: raise ValueError("LXMF cannot be initialised without a storage path")
|
if storagepath == None: raise ValueError("LXMF cannot be initialised without a storage path")
|
||||||
else:
|
else:
|
||||||
|
|
@ -287,10 +289,15 @@ class LXMRouter:
|
||||||
if destination_hash in self.delivery_destinations:
|
if destination_hash in self.delivery_destinations:
|
||||||
self.delivery_destinations[destination_hash].announce(app_data=self.get_announce_app_data(destination_hash), attached_interface=attached_interface)
|
self.delivery_destinations[destination_hash].announce(app_data=self.get_announce_app_data(destination_hash), attached_interface=attached_interface)
|
||||||
|
|
||||||
|
def get_propagation_node_announce_metadata(self):
|
||||||
|
metadata = {}
|
||||||
|
if self.name: metadata[PN_META_NAME] = str(self.name).encode("utf-8")
|
||||||
|
return metadata
|
||||||
|
|
||||||
def get_propagation_node_app_data(self):
|
def get_propagation_node_app_data(self):
|
||||||
|
metadata = self.get_propagation_node_announce_metadata()
|
||||||
node_state = self.propagation_node and not self.from_static_only
|
node_state = self.propagation_node and not self.from_static_only
|
||||||
stamp_cost = [self.propagation_stamp_cost, self.propagation_stamp_cost_flexibility, self.peering_cost]
|
stamp_cost = [self.propagation_stamp_cost, self.propagation_stamp_cost_flexibility, self.peering_cost]
|
||||||
metadata = {}
|
|
||||||
announce_data = [ False, # 0: Legacy LXMF PN support
|
announce_data = [ False, # 0: Legacy LXMF PN support
|
||||||
int(time.time()), # 1: Current node timebase
|
int(time.time()), # 1: Current node timebase
|
||||||
node_state, # 2: Boolean flag signalling propagation node state
|
node_state, # 2: Boolean flag signalling propagation node state
|
||||||
|
|
@ -737,6 +744,7 @@ class LXMRouter:
|
||||||
"type": "static" if peer_id in self.static_peers else "discovered",
|
"type": "static" if peer_id in self.static_peers else "discovered",
|
||||||
"state": peer.state,
|
"state": peer.state,
|
||||||
"alive": peer.alive,
|
"alive": peer.alive,
|
||||||
|
"name": peer.name,
|
||||||
"last_heard": int(peer.last_heard),
|
"last_heard": int(peer.last_heard),
|
||||||
"next_sync_attempt": peer.next_sync_attempt,
|
"next_sync_attempt": peer.next_sync_attempt,
|
||||||
"last_sync_attempt": peer.last_sync_attempt,
|
"last_sync_attempt": peer.last_sync_attempt,
|
||||||
|
|
@ -1834,6 +1842,7 @@ class LXMRouter:
|
||||||
peer = self.peers[destination_hash]
|
peer = self.peers[destination_hash]
|
||||||
if timestamp > peer.peering_timebase:
|
if timestamp > peer.peering_timebase:
|
||||||
peer.alive = True
|
peer.alive = True
|
||||||
|
peer.metadata = metadata
|
||||||
peer.sync_backoff = 0
|
peer.sync_backoff = 0
|
||||||
peer.next_sync_attempt = 0
|
peer.next_sync_attempt = 0
|
||||||
peer.peering_timebase = timestamp
|
peer.peering_timebase = timestamp
|
||||||
|
|
@ -1852,6 +1861,7 @@ class LXMRouter:
|
||||||
else:
|
else:
|
||||||
peer = LXMPeer(self, destination_hash, sync_strategy=self.default_sync_strategy)
|
peer = LXMPeer(self, destination_hash, sync_strategy=self.default_sync_strategy)
|
||||||
peer.alive = True
|
peer.alive = True
|
||||||
|
peer.metadata = metadata
|
||||||
peer.last_heard = time.time()
|
peer.last_heard = time.time()
|
||||||
peer.propagation_stamp_cost = propagation_stamp_cost
|
peer.propagation_stamp_cost = propagation_stamp_cost
|
||||||
peer.propagation_stamp_cost_flexibility = propagation_stamp_cost_flexibility
|
peer.propagation_stamp_cost_flexibility = propagation_stamp_cost_flexibility
|
||||||
|
|
|
||||||
|
|
@ -97,6 +97,11 @@ def apply_config():
|
||||||
else:
|
else:
|
||||||
active_configuration["enable_propagation_node"] = False
|
active_configuration["enable_propagation_node"] = False
|
||||||
|
|
||||||
|
if "propagation" in lxmd_config and "node_name" in lxmd_config["propagation"]:
|
||||||
|
active_configuration["node_name"] = lxmd_config["propagation"].get("node_name")
|
||||||
|
else:
|
||||||
|
active_configuration["node_name"] = None
|
||||||
|
|
||||||
if "propagation" in lxmd_config and "auth_required" in lxmd_config["propagation"]:
|
if "propagation" in lxmd_config and "auth_required" in lxmd_config["propagation"]:
|
||||||
active_configuration["auth_required"] = lxmd_config["propagation"].as_bool("auth_required")
|
active_configuration["auth_required"] = lxmd_config["propagation"].as_bool("auth_required")
|
||||||
else:
|
else:
|
||||||
|
|
@ -371,7 +376,8 @@ def program_setup(configdir = None, rnsconfigdir = None, run_pn = False, on_inbo
|
||||||
delivery_limit = active_configuration["delivery_transfer_max_accepted_size"],
|
delivery_limit = active_configuration["delivery_transfer_max_accepted_size"],
|
||||||
max_peers = active_configuration["max_peers"],
|
max_peers = active_configuration["max_peers"],
|
||||||
static_peers = active_configuration["static_peers"],
|
static_peers = active_configuration["static_peers"],
|
||||||
from_static_only = active_configuration["from_static_only"])
|
from_static_only = active_configuration["from_static_only"],
|
||||||
|
name = active_configuration["node_name"])
|
||||||
|
|
||||||
message_router.register_delivery_callback(lxmf_delivery)
|
message_router.register_delivery_callback(lxmf_delivery)
|
||||||
|
|
||||||
|
|
@ -647,8 +653,12 @@ def get_status(configdir = None, rnsconfigdir = None, verbosity = 0, quietness =
|
||||||
sstr = RNS.prettyspeed(p["str"]); sler = RNS.prettyspeed(p["ler"])
|
sstr = RNS.prettyspeed(p["str"]); sler = RNS.prettyspeed(p["ler"])
|
||||||
stl = RNS.prettysize(p["transfer_limit"]*1000); ssl = RNS.prettysize(p["sync_limit"]*1000)
|
stl = RNS.prettysize(p["transfer_limit"]*1000); ssl = RNS.prettysize(p["sync_limit"]*1000)
|
||||||
srxb = RNS.prettysize(p["rx_bytes"]); stxb = RNS.prettysize(p["tx_bytes"]); pmo = pm["offered"]; pmout = pm["outgoing"]
|
srxb = RNS.prettysize(p["rx_bytes"]); stxb = RNS.prettysize(p["tx_bytes"]); pmo = pm["offered"]; pmout = pm["outgoing"]
|
||||||
pmi = pm["incoming"]; pmuh = pm["unhandled"]
|
pmi = pm["incoming"]; pmuh = pm["unhandled"];
|
||||||
|
if p["name"] == None: nn = ""
|
||||||
|
else: nn = p["name"].strip().replace("\n", "").replace("\r", "")
|
||||||
|
if len(nn) > 45: nn = f"{nn[:45]}..."
|
||||||
print(f"{ind}{t}{RNS.prettyhexrep(peer_id)}")
|
print(f"{ind}{t}{RNS.prettyhexrep(peer_id)}")
|
||||||
|
if len(nn): print(f"{ind*2}Name : {nn}")
|
||||||
print(f"{ind*2}Status : {a}, {hs}, last heard {RNS.prettytime(h)} ago")
|
print(f"{ind*2}Status : {a}, {hs}, last heard {RNS.prettytime(h)} ago")
|
||||||
print(f"{ind*2}Costs : Propagation {psc} (flex {psf}), peering {pc}")
|
print(f"{ind*2}Costs : Propagation {psc} (flex {psf}), peering {pc}")
|
||||||
print(f"{ind*2}Sync key : {pk}")
|
print(f"{ind*2}Sync key : {pk}")
|
||||||
|
|
@ -717,6 +727,11 @@ __default_lxmd_config__ = """# This is an example LXM Daemon config file.
|
||||||
|
|
||||||
enable_node = no
|
enable_node = no
|
||||||
|
|
||||||
|
# An optional name for this node, included
|
||||||
|
# in announces.
|
||||||
|
|
||||||
|
# node_name = Anonymous Propagation Node
|
||||||
|
|
||||||
# Automatic announce interval in minutes.
|
# Automatic announce interval in minutes.
|
||||||
# 6 hours by default.
|
# 6 hours by default.
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue