Compare commits

...

26 Commits

Author SHA1 Message Date
Mark Qvist c7e5f4612a Updated documentation. 2021-09-11 16:11:44 +02:00
Mark Qvist f80e09cb5c Included six internally. 2021-09-11 16:03:35 +02:00
Mark Qvist 91d94f2f6f Fixed incorrect transfer size indications on single-packet request responses with msgpacked dictionaries as payloads. 2021-09-10 21:35:30 +02:00
Mark Qvist 53ca86ebfc Merge branch 'master' of github.com:markqvist/Reticulum 2021-09-05 20:06:21 +02:00
Mark Qvist 534bb28900 Fixed removal of non-existing receipts. 2021-09-05 20:05:12 +02:00
Mark Qvist 0de5ec73ad Merge pull request #8 from xtoddx/master
Record dependency on six
2021-09-05 15:02:49 +02:00
xtoddx c0f627b50b Record dependency on six 2021-09-04 22:58:42 -04:00
Mark Qvist 5629a062a5 Added resource window timeout recalculations during transfer. 2021-09-03 22:53:25 +02:00
Mark Qvist 83232f0446 Work on resource timing. 2021-09-03 22:20:16 +02:00
Mark Qvist aa794514b3 Work on resource timing. 2021-09-03 22:01:58 +02:00
Mark Qvist 07cf180ea8 Added continous resource timeout adjustment. Fixes missing response timeout check. 2021-09-03 21:08:20 +02:00
Mark Qvist 42a3d23e99 Optimised resource transfer timings. Improved request/response timeout handling. 2021-09-03 18:53:37 +02:00
Mark Qvist d28c888d1c Improved link request/response handling. 2021-09-03 16:24:47 +02:00
Mark Qvist 58d48c18f4 Improved link request/response handling. 2021-09-03 16:23:31 +02:00
Mark Qvist ecf0c55fd6 Improved link establishment. 2021-09-03 16:14:08 +02:00
Mark Qvist 32e4c262ef Improved link timeout handling. 2021-09-03 15:47:42 +02:00
Mark Qvist f87a6a57df Added link error handling. 2021-09-03 15:08:38 +02:00
Mark Qvist 6373f159f8 Added link error handling. 2021-09-03 14:42:59 +02:00
Mark Qvist ad9f548eeb Improved request timeout calculation and handling. 2021-09-03 14:22:53 +02:00
Mark Qvist 425f0153d0 Added flow control timeouts to AX.25 interface and optimised timeouts. 2021-09-03 10:56:49 +02:00
Mark Qvist cd9daaefee Removed option to allow unencrypted links. 2021-09-03 10:13:48 +02:00
Mark Qvist 0fe76d50f6 Improved documentation. 2021-09-02 20:35:42 +02:00
Mark Qvist 9562803bb3 Optimised sent Fernet token data. 2021-09-02 18:42:17 +02:00
Mark Qvist e9c89209c7 Optimised sent Fernet token data. 2021-09-02 18:34:58 +02:00
Mark Qvist cd8de64201 Implemented ability to change MTU. 2021-09-02 18:00:03 +02:00
Mark Qvist 40f7a6d359 Added resource HMU/part request hash filter. Fixes #7. 2021-09-02 14:44:53 +02:00
36 changed files with 1542 additions and 396 deletions
+1 -1
View File
@@ -358,7 +358,7 @@ def print_menu():
print("") print("")
while menu_mode == "downloading": while menu_mode == "downloading":
global current_download global current_download
percent = round(current_download.progress() * 100.0, 1) percent = round(current_download.get_progress() * 100.0, 1)
print(("\rProgress: "+str(percent)+" % "), end=' ') print(("\rProgress: "+str(percent)+" % "), end=' ')
sys.stdout.flush() sys.stdout.flush()
time.sleep(0.1) time.sleep(0.1)
+1 -1
View File
@@ -34,7 +34,7 @@ For more info, see [unsigned.io/projects/reticulum](https://unsigned.io/projects
- The API is very easy to use, and provides transfer progress - The API is very easy to use, and provides transfer progress
- Lightweight, flexible and expandable Request/Response mechanism - Lightweight, flexible and expandable Request/Response mechanism
- Efficient link establishment - Efficient link establishment
- Total bandwidth cost of setting up a link is 3 packets totalling 240 bytes - Total bandwidth cost of setting up a link is 3 packets totalling 237 bytes
- Low cost of keeping links open at only 0.62 bits per second - Low cost of keeping links open at only 0.62 bits per second
## Where can Reticulum be used? ## Where can Reticulum be used?
+19 -18
View File
@@ -34,12 +34,13 @@ class Identity:
""" """
# Non-configurable constants # Non-configurable constants
AES_HMAC_OVERHEAD = 58 # In bytes FERNET_VERSION = 0x80
FERNET_OVERHEAD = 54 # In bytes
AES128_BLOCKSIZE = 16 # In bytes AES128_BLOCKSIZE = 16 # In bytes
HASHLENGTH = 256 # In bits HASHLENGTH = 256 # In bits
SIGLENGTH = KEYSIZE # In bits SIGLENGTH = KEYSIZE # In bits
TRUNCATED_HASHLENGTH = 80 # In bits TRUNCATED_HASHLENGTH = RNS.Reticulum.TRUNCATED_HASHLENGTH
""" """
Constant specifying the truncated hash length (in bits) used by Reticulum Constant specifying the truncated hash length (in bits) used by Reticulum
for addressable hashes and other purposes. Non-configurable. for addressable hashes and other purposes. Non-configurable.
@@ -176,6 +177,22 @@ class Identity:
Identity.save_known_destinations() Identity.save_known_destinations()
@staticmethod
def from_bytes(prv_bytes):
"""
Create a new :ref:`RNS.Identity<api-identity>` instance from *bytes* of private key.
Can be used to load previously created and saved identities into Reticulum.
:param prv_bytes: The *bytes* of private a saved private key. **HAZARD!** Never use this to generate a new key by feeding random data in prv_bytes.
:returns: A :ref:`RNS.Identity<api-identity>` instance, or *None* if the *bytes* data was invalid.
"""
identity = Identity(create_keys=False)
if identity.load_private_key(prv_bytes):
return identity
else:
return None
@staticmethod @staticmethod
def from_file(path): def from_file(path):
""" """
@@ -209,22 +226,6 @@ class Identity:
RNS.log("Error while saving identity to "+str(path), RNS.LOG_ERROR) RNS.log("Error while saving identity to "+str(path), RNS.LOG_ERROR)
RNS.log("The contained exception was: "+str(e)) RNS.log("The contained exception was: "+str(e))
@staticmethod
def from_bytes(prv_bytes):
"""
Create a new :ref:`RNS.Identity<api-identity>` instance from *bytes* of private key.
Can be used to load previously created and saved identities into Reticulum.
:param prv_bytes: The *bytes* of private a saved private key. **HAZARD!** Never not use this to generate a new key by feeding random data in prv_bytes.
:returns: A :ref:`RNS.Identity<api-identity>` instance, or *None* if the *bytes* data was invalid.
"""
identity = Identity(create_keys=False)
if identity.load_private_key(prv_bytes):
return identity
else:
return None
def __init__(self,create_keys=True): def __init__(self,create_keys=True):
# Initialize keys to none # Initialize keys to none
self.prv = None self.prv = None
+10 -7
View File
@@ -62,13 +62,12 @@ class AX25KISSInterface(Interface):
self.stopbits = stopbits self.stopbits = stopbits
self.timeout = 100 self.timeout = 100
self.online = False self.online = False
# TODO: Sane default and make this configurable
# TODO: Changed to 25ms instead of 100ms, check it
self.txdelay = 0.025
self.packet_queue = [] self.packet_queue = []
self.flow_control = flow_control self.flow_control = flow_control
self.interface_ready = False self.interface_ready = False
self.flow_control_timeout = 5
self.flow_control_locked = time.time()
if (len(self.src_call) < 3 or len(self.src_call) > 6): if (len(self.src_call) < 3 or len(self.src_call) > 6):
raise ValueError("Invalid callsign for "+str(self)) raise ValueError("Invalid callsign for "+str(self))
@@ -197,6 +196,7 @@ class AX25KISSInterface(Interface):
if self.interface_ready: if self.interface_ready:
if self.flow_control: if self.flow_control:
self.interface_ready = False self.interface_ready = False
self.flow_control_locked = time.time()
encoded_dst_ssid = bytes([0x60 | (self.dst_ssid << 1)]) encoded_dst_ssid = bytes([0x60 | (self.dst_ssid << 1)])
encoded_src_ssid = bytes([0x60 | (self.src_ssid << 1) | 0x01]) encoded_src_ssid = bytes([0x60 | (self.src_ssid << 1) | 0x01])
@@ -223,9 +223,6 @@ class AX25KISSInterface(Interface):
data = data.replace(bytes([0xc0]), bytes([0xdb])+bytes([0xdc])) data = data.replace(bytes([0xc0]), bytes([0xdb])+bytes([0xdc]))
kiss_frame = bytes([KISS.FEND])+bytes([0x00])+data+bytes([KISS.FEND]) kiss_frame = bytes([KISS.FEND])+bytes([0x00])+data+bytes([KISS.FEND])
if (self.txdelay > 0):
sleep(self.txdelay)
written = self.serial.write(kiss_frame) written = self.serial.write(kiss_frame)
if written != len(kiss_frame): if written != len(kiss_frame):
if self.flow_control: if self.flow_control:
@@ -293,7 +290,13 @@ class AX25KISSInterface(Interface):
in_frame = False in_frame = False
command = KISS.CMD_UNKNOWN command = KISS.CMD_UNKNOWN
escape = False escape = False
sleep(0.08) sleep(0.05)
if self.flow_control:
if not self.interface_ready:
if time.time() > self.flow_control_locked + self.flow_control_timeout:
RNS.log("Interface "+str(self)+" is unlocking flow control due to time-out. This should not happen. Your hardware might have missed a flow-control READY command, or maybe it does not support flow-control.", RNS.LOG_WARNING)
self.process_queue()
except Exception as e: except Exception as e:
self.online = False self.online = False
-1
View File
@@ -11,5 +11,4 @@ class Interface:
pass pass
def get_hash(self): def get_hash(self):
# TODO: Maybe expand this to something more unique
return RNS.Identity.full_hash(str(self).encode("utf-8")) return RNS.Identity.full_hash(str(self).encode("utf-8"))
+3 -3
View File
@@ -60,7 +60,7 @@ class KISSInterface(Interface):
self.packet_queue = [] self.packet_queue = []
self.flow_control = flow_control self.flow_control = flow_control
self.interface_ready = False self.interface_ready = False
self.flow_control_timeout = 10 self.flow_control_timeout = 5
self.flow_control_locked = time.time() self.flow_control_locked = time.time()
self.preamble = preamble if preamble != None else 350; self.preamble = preamble if preamble != None else 350;
@@ -259,12 +259,12 @@ class KISSInterface(Interface):
in_frame = False in_frame = False
command = KISS.CMD_UNKNOWN command = KISS.CMD_UNKNOWN
escape = False escape = False
sleep(0.08) sleep(0.05)
if self.flow_control: if self.flow_control:
if not self.interface_ready: if not self.interface_ready:
if time.time() > self.flow_control_locked + self.flow_control_timeout: if time.time() > self.flow_control_locked + self.flow_control_timeout:
RNS.log("Interface "+str(self)+" is unlocking flow control due to time-out. This should not happen. Your hardware might have missed a flow-control READY command.", RNS.LOG_WARNING) RNS.log("Interface "+str(self)+" is unlocking flow control due to time-out. This should not happen. Your hardware might have missed a flow-control READY command, or maybe it does not support flow-control.", RNS.LOG_WARNING)
self.process_queue() self.process_queue()
if self.beacon_i != None and self.beacon_d != None: if self.beacon_i != None and self.beacon_d != None:
+121 -65
View File
@@ -27,14 +27,13 @@ class LinkCallbacks:
class Link: class Link:
""" """
This class. This class is used to establish and manage links to other peers. When a
link instance is created, Reticulum will attempt to establish verified
connectivity with the specified destination.
:param destination: A :ref:`RNS.Destination<api-destination>` instance which to establish a link to. :param destination: A :ref:`RNS.Destination<api-destination>` instance which to establish a link to.
:param established_callback: A function or method with the signature *callback(link)* to be called when the link has been established. :param established_callback: An optional function or method with the signature *callback(link)* to be called when the link has been established.
:param closed_callback: A function or method with the signature *callback(link)* to be called when the link is closed. :param closed_callback: An optional function or method with the signature *callback(link)* to be called when the link is closed.
:param owner: Internal use by :ref:`RNS.Transport<api-Transport>`, ignore this argument.
:param peer_pub_bytes: Internal use, ignore this argument.
:param peer_sig_pub_bytes: Internal use, ignore this argument.
""" """
CURVE = RNS.Identity.CURVE CURVE = RNS.Identity.CURVE
""" """
@@ -44,16 +43,18 @@ class Link:
ECPUBSIZE = 32+32 ECPUBSIZE = 32+32
KEYSIZE = 32 KEYSIZE = 32
MDU = math.floor((RNS.Reticulum.MDU-RNS.Identity.AES_HMAC_OVERHEAD)/RNS.Identity.AES128_BLOCKSIZE)*RNS.Identity.AES128_BLOCKSIZE - 1 MDU = math.floor((RNS.Reticulum.MTU-RNS.Reticulum.HEADER_MINSIZE-RNS.Identity.FERNET_OVERHEAD)/RNS.Identity.AES128_BLOCKSIZE)*RNS.Identity.AES128_BLOCKSIZE - 1
# This value is set at a reasonable # This value is set at a reasonable level for a 1 Kb/s channel.
# level for a 1 Kb/s channel. #
ESTABLISHMENT_TIMEOUT_PER_HOP = 3 # TODO: Find a way to automatically raise or lower this according to
# channel bandwidth and utilisation.
ESTABLISHMENT_TIMEOUT_PER_HOP = 5
""" """
Default timeout for link establishment in seconds per hop to destination. Default timeout for link establishment in seconds per hop to destination.
""" """
TRAFFIC_TIMEOUT_FACTOR = 20 TRAFFIC_TIMEOUT_FACTOR = 6
KEEPALIVE_TIMEOUT_FACTOR = 4 KEEPALIVE_TIMEOUT_FACTOR = 4
STALE_GRACE = 2 STALE_GRACE = 2
KEEPALIVE = 360 KEEPALIVE = 360
@@ -131,7 +132,6 @@ class Link:
self.destination = destination self.destination = destination
self.attached_interface = None self.attached_interface = None
self.__remote_identity = None self.__remote_identity = None
self.__encryption_disabled = False
if self.destination == None: if self.destination == None:
self.initiator = False self.initiator = False
self.prv = self.owner.identity.prv self.prv = self.owner.identity.prv
@@ -232,6 +232,7 @@ class Link:
self.had_outbound() self.had_outbound()
def validate_proof(self, packet): def validate_proof(self, packet):
if self.status == Link.HANDSHAKE:
if self.initiator and len(packet.data) == RNS.Identity.SIGLENGTH//8: if self.initiator and len(packet.data) == RNS.Identity.SIGLENGTH//8:
signed_data = self.link_id+self.peer_pub_bytes+self.peer_sig_pub_bytes signed_data = self.link_id+self.peer_pub_bytes+self.peer_sig_pub_bytes
signature = packet.data[:RNS.Identity.SIGLENGTH//8] signature = packet.data[:RNS.Identity.SIGLENGTH//8]
@@ -284,20 +285,23 @@ class Link:
:param failed_callback: An optional function or method with the signature *failed_callback(request_receipt)* to be called when a request fails. See the :ref:`Request Example<example-request>` for more info. :param failed_callback: An optional function or method with the signature *failed_callback(request_receipt)* to be called when a request fails. See the :ref:`Request Example<example-request>` for more info.
:param progress_callback: An optional function or method with the signature *progress_callback(request_receipt)* to be called when progress is made receiving the response. Progress can be accessed as a float between 0.0 and 1.0 by the *request_receipt.progress* property. :param progress_callback: An optional function or method with the signature *progress_callback(request_receipt)* to be called when progress is made receiving the response. Progress can be accessed as a float between 0.0 and 1.0 by the *request_receipt.progress* property.
:param timeout: An optional timeout in seconds for the request. If *None* is supplied it will be calculated based on link RTT. :param timeout: An optional timeout in seconds for the request. If *None* is supplied it will be calculated based on link RTT.
:returns: A :ref:`RNS.RequestReceipt<api-requestreceipt>` instance if the request was sent, or *False* if it was not.
""" """
request_path_hash = RNS.Identity.truncated_hash(path.encode("utf-8")) request_path_hash = RNS.Identity.truncated_hash(path.encode("utf-8"))
unpacked_request = [time.time(), request_path_hash, data] unpacked_request = [time.time(), request_path_hash, data]
packed_request = umsgpack.packb(unpacked_request) packed_request = umsgpack.packb(unpacked_request)
if timeout == None: if timeout == None:
timeout = self.rtt * self.traffic_timeout_factor timeout = self.rtt * self.traffic_timeout_factor + RNS.Resource.RESPONSE_MAX_GRACE_TIME
if len(packed_request) <= Link.MDU: if len(packed_request) <= Link.MDU:
request_packet = RNS.Packet(self, packed_request, RNS.Packet.DATA, context = RNS.Packet.REQUEST) request_packet = RNS.Packet(self, packed_request, RNS.Packet.DATA, context = RNS.Packet.REQUEST)
packet_receipt = request_packet.send() packet_receipt = request_packet.send()
if packet_receipt == False:
return False
else:
packet_receipt.set_timeout(timeout) packet_receipt.set_timeout(timeout)
return RequestReceipt( return RequestReceipt(
self, self,
packet_receipt = packet_receipt, packet_receipt = packet_receipt,
@@ -445,7 +449,11 @@ class Link:
next_check = self.request_time + self.establishment_timeout next_check = self.request_time + self.establishment_timeout
sleep_time = next_check - time.time() sleep_time = next_check - time.time()
if time.time() >= self.request_time + self.establishment_timeout: if time.time() >= self.request_time + self.establishment_timeout:
if self.initiator:
RNS.log("Timeout waiting link request proof", RNS.LOG_DEBUG)
else:
RNS.log("Timeout waiting for RTT packet from link initiator", RNS.LOG_DEBUG) RNS.log("Timeout waiting for RTT packet from link initiator", RNS.LOG_DEBUG)
self.status = Link.CLOSED self.status = Link.CLOSED
self.teardown_reason = Link.TIMEOUT self.teardown_reason = Link.TIMEOUT
self.link_closed() self.link_closed()
@@ -483,6 +491,7 @@ class Link:
self.had_outbound() self.had_outbound()
def handle_request(self, request_id, unpacked_request): def handle_request(self, request_id, unpacked_request):
if self.status == Link.ACTIVE:
requested_at = unpacked_request[0] requested_at = unpacked_request[0]
path_hash = unpacked_request[1] path_hash = unpacked_request[1]
request_data = unpacked_request[2] request_data = unpacked_request[2]
@@ -516,12 +525,15 @@ class Link:
identity_string = RNS.prettyhexrep(self.get_remote_identity()) if self.get_remote_identity() != None else "<Unknown>" identity_string = RNS.prettyhexrep(self.get_remote_identity()) if self.get_remote_identity() != None else "<Unknown>"
RNS.log("Request "+RNS.prettyhexrep(request_id)+" from "+identity_string+" not allowed for: "+str(path), RNS.LOG_DEBUG) RNS.log("Request "+RNS.prettyhexrep(request_id)+" from "+identity_string+" not allowed for: "+str(path), RNS.LOG_DEBUG)
def handle_response(self, request_id, response_data): def handle_response(self, request_id, response_data, response_size, response_transfer_size):
if self.status == Link.ACTIVE:
remove = None remove = None
for pending_request in self.pending_requests: for pending_request in self.pending_requests:
if pending_request.request_id == request_id: if pending_request.request_id == request_id:
remove = pending_request remove = pending_request
try: try:
pending_request.response_size = response_size
pending_request.response_transfer_size = response_transfer_size
pending_request.response_received(response_data) pending_request.response_received(response_data)
except Exception as e: except Exception as e:
RNS.log("Error occurred while handling response. The contained exception was: "+str(e), RNS.LOG_ERROR) RNS.log("Error occurred while handling response. The contained exception was: "+str(e), RNS.LOG_ERROR)
@@ -549,9 +561,12 @@ class Link:
request_id = unpacked_response[0] request_id = unpacked_response[0]
response_data = unpacked_response[1] response_data = unpacked_response[1]
self.handle_response(request_id, response_data) self.handle_response(request_id, response_data, resource.total_size, resource.size)
else: else:
RNS.log("Incoming response resource failed with status: "+RNS.hexrep([resource.status]), RNS.LOG_DEBUG) RNS.log("Incoming response resource failed with status: "+RNS.hexrep([resource.status]), RNS.LOG_DEBUG)
for pending_request in self.pending_requests:
if pending_request.request_id == resource.request_id:
pending_request.request_timed_out(None)
def receive(self, packet): def receive(self, packet):
self.watchdog_lock = True self.watchdog_lock = True
@@ -610,7 +625,8 @@ class Link:
unpacked_response = umsgpack.unpackb(packed_response) unpacked_response = umsgpack.unpackb(packed_response)
request_id = unpacked_response[0] request_id = unpacked_response[0]
response_data = unpacked_response[1] response_data = unpacked_response[1]
self.handle_response(request_id, response_data) transfer_size = len(umsgpack.packb(response_data))-2
self.handle_response(request_id, response_data, transfer_size, transfer_size)
except Exception as e: except Exception as e:
RNS.log("Error occurred while handling response. The contained exception was: "+str(e), RNS.LOG_ERROR) RNS.log("Error occurred while handling response. The contained exception was: "+str(e), RNS.LOG_ERROR)
@@ -630,7 +646,7 @@ class Link:
request_id = RNS.ResourceAdvertisement.get_request_id(packet) request_id = RNS.ResourceAdvertisement.get_request_id(packet)
for pending_request in self.pending_requests: for pending_request in self.pending_requests:
if pending_request.request_id == request_id: if pending_request.request_id == request_id:
RNS.Resource.accept(packet, callback=self.response_resource_concluded, progress_callback=pending_request.response_resource_progress) RNS.Resource.accept(packet, callback=self.response_resource_concluded, progress_callback=pending_request.response_resource_progress, request_id = request_id)
pending_request.response_size = RNS.ResourceAdvertisement.get_size(packet) pending_request.response_size = RNS.ResourceAdvertisement.get_size(packet)
pending_request.response_transfer_size = RNS.ResourceAdvertisement.get_transfer_size(packet) pending_request.response_transfer_size = RNS.ResourceAdvertisement.get_transfer_size(packet)
pending_request.started_at = time.time() pending_request.started_at = time.time()
@@ -651,6 +667,10 @@ class Link:
resource_hash = plaintext[1:RNS.Identity.HASHLENGTH//8+1] resource_hash = plaintext[1:RNS.Identity.HASHLENGTH//8+1]
for resource in self.outgoing_resources: for resource in self.outgoing_resources:
if resource.hash == resource_hash: if resource.hash == resource_hash:
# We need to check that this request has not been
# received before in order to avoid sequencing errors.
if not packet.packet_hash in resource.req_hashlist:
resource.req_hashlist.append(packet.packet_hash)
resource.request(plaintext) resource.request(plaintext)
elif packet.context == RNS.Packet.RESOURCE_HMU: elif packet.context == RNS.Packet.RESOURCE_HMU:
@@ -693,27 +713,36 @@ class Link:
def encrypt(self, plaintext): def encrypt(self, plaintext):
if self.__encryption_disabled:
return plaintext
try: try:
if not self.fernet: if not self.fernet:
try:
self.fernet = Fernet(base64.urlsafe_b64encode(self.derived_key)) self.fernet = Fernet(base64.urlsafe_b64encode(self.derived_key))
except Exception as e:
RNS.log("Could not "+str(self)+" instantiate Fernet while performin encryption on link. The contained exception was: "+str(e), RNS.LOG_ERROR)
raise e
ciphertext = base64.urlsafe_b64decode(self.fernet.encrypt(plaintext)) # The fernet token VERSION field is stripped here and
# reinserted on the receiving end, since it is always
# set to 0x80.
#
# Since we're also quite content with supporting time-
# stamps until the year 8921556 AD, we'll also strip 2
# bytes from the timestamp field and reinsert those as
# 0x00 when received.
ciphertext = base64.urlsafe_b64decode(self.fernet.encrypt(plaintext))[3:]
return ciphertext return ciphertext
except Exception as e: except Exception as e:
RNS.log("Encryption on link "+str(self)+" failed. The contained exception was: "+str(e), RNS.LOG_ERROR) RNS.log("Encryption on link "+str(self)+" failed. The contained exception was: "+str(e), RNS.LOG_ERROR)
raise e raise e
def decrypt(self, ciphertext): def decrypt(self, ciphertext):
if self.__encryption_disabled:
return ciphertext
try: try:
if not self.fernet: if not self.fernet:
self.fernet = Fernet(base64.urlsafe_b64encode(self.derived_key)) self.fernet = Fernet(base64.urlsafe_b64encode(self.derived_key))
plaintext = self.fernet.decrypt(base64.urlsafe_b64encode(ciphertext)) plaintext = self.fernet.decrypt(base64.urlsafe_b64encode(bytes([RNS.Identity.FERNET_VERSION, 0x00, 0x00])+ciphertext))
return plaintext return plaintext
except Exception as e: except Exception as e:
RNS.log("Decryption failed on link "+str(self)+". The contained exception was: "+str(e), RNS.LOG_ERROR) RNS.log("Decryption failed on link "+str(self)+". The contained exception was: "+str(e), RNS.LOG_ERROR)
@@ -827,37 +856,22 @@ class Link:
else: else:
return True return True
def disable_encryption(self):
"""
HAZARDOUS. This will downgrade the link to encryptionless. All
information over the link will be sent in plaintext. Never use
this in production applications. Should only be used for debugging
purposes, and will disappear in a future version.
If encryptionless links are not explicitly allowed in the users
configuration file, Reticulum will terminate itself along with the
client application and throw an error message to the user.
"""
if (RNS.Reticulum.should_allow_unencrypted()):
RNS.log("The link "+str(self)+" was downgraded to an encryptionless link", RNS.LOG_NOTICE)
self.__encryption_disabled = True
else:
RNS.log("Attempt to disable encryption on link, but encryptionless links are not allowed by config.", RNS.LOG_CRITICAL)
RNS.log("Shutting down Reticulum now!", RNS.LOG_CRITICAL)
RNS.panic()
def encryption_disabled(self):
return self.__encryption_disabled
def __str__(self): def __str__(self):
return RNS.prettyhexrep(self.link_id) return RNS.prettyhexrep(self.link_id)
class RequestReceipt(): class RequestReceipt():
"""
An instance of this class is returned by the ``request`` method of ``RNS.Link``
instances. It should never be instantiated manually. It provides methods to
check status, response time and response data when the request concludes.
"""
FAILED = 0x00 FAILED = 0x00
SENT = 0x01 SENT = 0x01
DELIVERED = 0x02 DELIVERED = 0x02
READY = 0x03 RECEIVING = 0x03
READY = 0x04
def __init__(self, link, packet_receipt = None, resource = None, response_callback = None, failed_callback = None, progress_callback = None, timeout = None): def __init__(self, link, packet_receipt = None, resource = None, response_callback = None, failed_callback = None, progress_callback = None, timeout = None):
self.packet_receipt = packet_receipt self.packet_receipt = packet_receipt
@@ -904,9 +918,9 @@ class RequestReceipt():
self.started_at = time.time() self.started_at = time.time()
self.status = RequestReceipt.DELIVERED self.status = RequestReceipt.DELIVERED
self.__resource_response_timeout = time.time()+self.timeout self.__resource_response_timeout = time.time()+self.timeout
load_thread = threading.Thread(target=self.__resource_response_timeout_job) response_timeout_thread = threading.Thread(target=self.__response_timeout_job)
load_thread.setDaemon(True) response_timeout_thread.setDaemon(True)
load_thread.start() response_timeout_thread.start()
else: else:
RNS.log("Sending request "+RNS.prettyhexrep(self.request_id)+" as resource failed with status: "+RNS.hexrep([resource.status]), RNS.LOG_DEBUG) RNS.log("Sending request "+RNS.prettyhexrep(self.request_id)+" as resource failed with status: "+RNS.hexrep([resource.status]), RNS.LOG_DEBUG)
self.status = RequestReceipt.FAILED self.status = RequestReceipt.FAILED
@@ -917,6 +931,15 @@ class RequestReceipt():
self.callbacks.failed(self) self.callbacks.failed(self)
def __response_timeout_job(self):
while self.status == RequestReceipt.DELIVERED:
now = time.time()
if now > self.__resource_response_timeout:
self.request_timed_out(None)
time.sleep(0.1)
def request_timed_out(self, packet_receipt): def request_timed_out(self, packet_receipt):
self.status = RequestReceipt.FAILED self.status = RequestReceipt.FAILED
self.concluded_at = time.time() self.concluded_at = time.time()
@@ -925,37 +948,38 @@ class RequestReceipt():
if self.callbacks.failed != None: if self.callbacks.failed != None:
self.callbacks.failed(self) self.callbacks.failed(self)
def response_resource_progress(self, resource): def response_resource_progress(self, resource):
self.progress = resource.progress() if not self.status == RequestReceipt.FAILED:
self.__resource_response_timeout = time.time()+self.timeout self.status = RequestReceipt.RECEIVING
if self.packet_receipt != None:
self.packet_receipt.status = RNS.PacketReceipt.DELIVERED
self.packet_receipt.proved = True
self.packet_receipt.concluded_at = time.time()
if self.packet_receipt.callbacks.delivery != None:
self.packet_receipt.callbacks.delivery(self.packet_receipt)
self.progress = resource.get_progress()
if self.callbacks.progress != None: if self.callbacks.progress != None:
self.callbacks.progress(self) self.callbacks.progress(self)
else:
def __resource_response_timeout_job(self): resource.cancel()
while self.status == RequestReceipt.DELIVERED:
if time.time() > self.__resource_response_timeout:
self.request_timed_out(None)
time.sleep(0.1)
def response_received(self, response): def response_received(self, response):
if not self.status == RequestReceipt.FAILED:
self.progress = 1.0 self.progress = 1.0
self.response = response self.response = response
self.status = RequestReceipt.READY self.status = RequestReceipt.READY
self.response_concluded_at = time.time() self.response_concluded_at = time.time()
if len(response) <= Link.MDU:
self.response_size = len(response)
self.response_transfer_size = len(response)
if self.packet_receipt != None: if self.packet_receipt != None:
self.packet_receipt.status = RNS.PacketReceipt.DELIVERED self.packet_receipt.status = RNS.PacketReceipt.DELIVERED
self.packet_receipt.proved = True self.packet_receipt.proved = True
self.packet_receipt.concluded_at = time.time() self.packet_receipt.concluded_at = time.time()
if self.packet_receipt.callbacks.delivery != None: if self.packet_receipt.callbacks.delivery != None:
self.packet_receipt.callbacks.delivery(self) self.packet_receipt.callbacks.delivery(self.packet_receipt)
if self.callbacks.progress != None: if self.callbacks.progress != None:
self.callbacks.progress(self) self.callbacks.progress(self)
@@ -963,9 +987,41 @@ class RequestReceipt():
if self.callbacks.response != None: if self.callbacks.response != None:
self.callbacks.response(self) self.callbacks.response(self)
def response_time(self): def get_request_id(self):
"""
:returns: The request ID as *bytes*.
"""
return self.request_id
def get_status(self):
"""
:returns: The current status of the request, one of ``RNS.RequestReceipt.FAILED``, ``RNS.RequestReceipt.SENT``, ``RNS.RequestReceipt.DELIVERED``, ``RNS.RequestReceipt.READY``.
"""
return self.status
def get_progress(self):
"""
:returns: The progress of a response being received as a *float* between 0.0 and 1.0.
"""
return self.progress
def get_response(self):
"""
:returns: The response as *bytes* if it is ready, otherwise *None*.
"""
if self.status == RequestReceipt.READY:
return self.response
else:
return None
def get_response_time(self):
"""
:returns: The response time of the request in seconds.
"""
if self.status == RequestReceipt.READY: if self.status == RequestReceipt.READY:
return self.response_concluded_at - self.started_at return self.response_concluded_at - self.started_at
else:
return None
+3 -8
View File
@@ -20,11 +20,6 @@ class Packet:
:param destination: A :ref:`RNS.Destination<api-destination>` instance to which the packet will be sent. :param destination: A :ref:`RNS.Destination<api-destination>` instance to which the packet will be sent.
:param data: The data payload to be included in the packet as *bytes*. :param data: The data payload to be included in the packet as *bytes*.
:param create_receipt: Specifies whether a :ref:`RNS.PacketReceipt<api-packetreceipt>` should be created when instantiating the packet. :param create_receipt: Specifies whether a :ref:`RNS.PacketReceipt<api-packetreceipt>` should be created when instantiating the packet.
:param type: Internal use by :ref:`RNS.Transport<api-transport>`. Defaults to ``RNS.Packet.DATA``, and should not be specified.
:param context: Internal use by :ref:`RNS.Transport<api-transport>`. Ignore.
:param transport_type: Internal use by :ref:`RNS.Transport<api-transport>`. Ignore.
:param transport_id: Internal use by :ref:`RNS.Transport<api-transport>`. Ignore.
:param attached_interface: Internal use by :ref:`RNS.Transport<api-transport>`. Ignore.
""" """
# Packet types # Packet types
@@ -71,7 +66,7 @@ class Packet:
# With an MTU of 500, the maximum of data we can # With an MTU of 500, the maximum of data we can
# send in a single encrypted packet is given by # send in a single encrypted packet is given by
# the below calculation; 383 bytes. # the below calculation; 383 bytes.
ENCRYPTED_MDU = math.floor((RNS.Reticulum.MDU-RNS.Identity.AES_HMAC_OVERHEAD-RNS.Identity.KEYSIZE//16)/RNS.Identity.AES128_BLOCKSIZE)*RNS.Identity.AES128_BLOCKSIZE - 1 ENCRYPTED_MDU = math.floor((RNS.Reticulum.MDU-RNS.Identity.FERNET_OVERHEAD-RNS.Identity.KEYSIZE//16)/RNS.Identity.AES128_BLOCKSIZE)*RNS.Identity.AES128_BLOCKSIZE - 1
""" """
The maximum size of the payload data in a single encrypted packet The maximum size of the payload data in a single encrypted packet
""" """
@@ -309,8 +304,8 @@ class PacketReceipt:
""" """
The PacketReceipt class is used to receive notifications about The PacketReceipt class is used to receive notifications about
:ref:`RNS.Packet<api-packet>` instances sent over the network. Instances :ref:`RNS.Packet<api-packet>` instances sent over the network. Instances
of this class should never be created manually, but always returned of this class are never created manually, but always returned from
from a the *send()* method of a :ref:`RNS.Packet<api-packet>` instance. the *send()* method of a :ref:`RNS.Packet<api-packet>` instance.
""" """
# Receipt status constants # Receipt status constants
FAILED = 0x00 FAILED = 0x00
+61 -30
View File
@@ -15,14 +15,10 @@ class Resource:
:param data: The data to be transferred. Can be *bytes* or an open *file handle*. See the :ref:`Filetransfer Example<example-filetransfer>` for details. :param data: The data to be transferred. Can be *bytes* or an open *file handle*. See the :ref:`Filetransfer Example<example-filetransfer>` for details.
:param link: The :ref:`RNS.Link<api-link>` instance on which to transfer the data. :param link: The :ref:`RNS.Link<api-link>` instance on which to transfer the data.
:param advertise: Whether to automatically advertise the resource. Can be *True* or *False*. :param advertise: Optional. Whether to automatically advertise the resource. Can be *True* or *False*.
:param auto_compress: Whether to auto-compress the resource. Can be *True* or *False*. :param auto_compress: Optional. Whether to auto-compress the resource. Can be *True* or *False*.
:param callback: A *callable* with the signature *callback(resource)*. Will be called when the resource transfer concludes. :param callback: An optional *callable* with the signature *callback(resource)*. Will be called when the resource transfer concludes.
:param progress_callback: A *callable* with the signature *callback(resource)*. Will be called whenever the resource transfer progress is updated. :param progress_callback: An optional *callable* with the signature *callback(resource)*. Will be called whenever the resource transfer progress is updated.
:param segment_index: Internal use, ignore.
:param original_hash: Internal use, ignore.
:param is_request: Internal use, ignore.
:param is_response: Internal use, ignore.
""" """
WINDOW_FLEXIBILITY = 4 WINDOW_FLEXIBILITY = 4
WINDOW_MIN = 1 WINDOW_MIN = 1
@@ -36,26 +32,32 @@ class Resource:
# maximum size a resource should be, if # maximum size a resource should be, if
# it is to be handled within reasonable # it is to be handled within reasonable
# time constraint, even on small systems. # time constraint, even on small systems.
#
# A small system in this regard is # A small system in this regard is
# defined as a Raspberry Pi, which should # defined as a Raspberry Pi, which should
# be able to compress, encrypt and hash-map # be able to compress, encrypt and hash-map
# the resource in about 10 seconds. # the resource in about 10 seconds.
#
# This constant will be used when determining # This constant will be used when determining
# how to sequence the sending of large resources. # how to sequence the sending of large resources.
MAX_EFFICIENT_SIZE = 16 * 1024 * 1024 #
# Capped at 16777215 (0xFFFFFF) per segment to
# fit in 3 bytes in resource advertisements.
MAX_EFFICIENT_SIZE = 16 * 1024 * 1024 - 1
RESPONSE_MAX_GRACE_TIME = 10
# The maximum size to auto-compress with # The maximum size to auto-compress with
# bz2 before sending. # bz2 before sending.
AUTO_COMPRESS_MAX_SIZE = MAX_EFFICIENT_SIZE AUTO_COMPRESS_MAX_SIZE = MAX_EFFICIENT_SIZE
# TODO: Should be allocated more PART_TIMEOUT_FACTOR = 4
# intelligently PART_TIMEOUT_FACTOR_AFTER_RTT = 2
MAX_RETRIES = 5 MAX_RETRIES = 5
SENDER_GRACE_TIME = 10 SENDER_GRACE_TIME = 10
RETRY_GRACE_TIME = 0.25 RETRY_GRACE_TIME = 0.25
WATCHDOG_MAX_SLEEP = 1
HASHMAP_IS_NOT_EXHAUSTED = 0x00 HASHMAP_IS_NOT_EXHAUSTED = 0x00
HASHMAP_IS_EXHAUSTED = 0xFF HASHMAP_IS_EXHAUSTED = 0xFF
@@ -71,11 +73,11 @@ class Resource:
CORRUPT = 0x08 CORRUPT = 0x08
@staticmethod @staticmethod
def accept(advertisement_packet, callback=None, progress_callback = None): def accept(advertisement_packet, callback=None, progress_callback = None, request_id = None):
try: try:
adv = ResourceAdvertisement.unpack(advertisement_packet.plaintext) adv = ResourceAdvertisement.unpack(advertisement_packet.plaintext)
resource = Resource(None, advertisement_packet.link) resource = Resource(None, advertisement_packet.link, request_id = request_id)
resource.status = Resource.TRANSFERRING resource.status = Resource.TRANSFERRING
resource.flags = adv.f resource.flags = adv.f
@@ -183,6 +185,7 @@ class Resource:
self.max_retries = Resource.MAX_RETRIES self.max_retries = Resource.MAX_RETRIES
self.retries_left = self.max_retries self.retries_left = self.max_retries
self.timeout_factor = self.link.traffic_timeout_factor self.timeout_factor = self.link.traffic_timeout_factor
self.part_timeout_factor = Resource.PART_TIMEOUT_FACTOR
self.sender_grace_time = Resource.SENDER_GRACE_TIME self.sender_grace_time = Resource.SENDER_GRACE_TIME
self.hmu_retry_ok = False self.hmu_retry_ok = False
self.watchdog_lock = False self.watchdog_lock = False
@@ -192,6 +195,7 @@ class Resource:
self.request_id = request_id self.request_id = request_id
self.is_response = is_response self.is_response = is_response
self.req_hashlist = []
self.receiver_min_consecutive_height = 0 self.receiver_min_consecutive_height = 0
if timeout != None: if timeout != None:
@@ -241,11 +245,8 @@ class Resource:
# make optimal use of packet MTU on an entire # make optimal use of packet MTU on an entire
# encrypted stream. The Resource instance will # encrypted stream. The Resource instance will
# use it's underlying link directly to encrypt. # use it's underlying link directly to encrypt.
if not self.link.encryption_disabled():
self.data = self.link.encrypt(self.data) self.data = self.link.encrypt(self.data)
self.encrypted = True self.encrypted = True
else:
self.encrypted = False
self.size = len(self.data) self.size = len(self.data)
self.sent_parts = 0 self.sent_parts = 0
@@ -394,8 +395,24 @@ class Resource:
elif self.status == Resource.TRANSFERRING: elif self.status == Resource.TRANSFERRING:
if not self.initiator: if not self.initiator:
rtt = self.link.rtt if self.rtt == None else self.rtt
sleep_time = self.last_activity + (rtt*self.timeout_factor) + Resource.RETRY_GRACE_TIME - time.time() if self.rtt == None:
rtt = self.link.rtt
else:
rtt = self.rtt
window_remaining = self.outstanding_parts
sleep_time = self.last_activity + (rtt*(self.part_timeout_factor+window_remaining)) + Resource.RETRY_GRACE_TIME - time.time()
# TODO: Remove debug info
# RNS.log("rtt "+str(rtt))
# RNS.log("ptof "+str(self.part_timeout_factor))
# RNS.log("wait "+str((rtt*self.part_timeout_factor) + Resource.RETRY_GRACE_TIME))
# RNS.log("sleep "+str(sleep_time))
# RNS.log("wndw "+str(self.window))
# RNS.log("wndwr "+str(window_remaining))
# RNS.log("")
if sleep_time < 0: if sleep_time < 0:
if self.retries_left > 0: if self.retries_left > 0:
@@ -446,7 +463,7 @@ class Resource:
self.cancel() self.cancel()
if sleep_time != None: if sleep_time != None:
sleep(sleep_time) sleep(min(sleep_time, Resource.WATCHDOG_MAX_SLEEP))
def assemble(self): def assemble(self):
if not self.status == Resource.FAILED: if not self.status == Resource.FAILED:
@@ -545,11 +562,15 @@ class Resource:
if self.req_resp == None: if self.req_resp == None:
self.req_resp = self.last_activity self.req_resp = self.last_activity
rtt = self.req_resp-self.req_sent rtt = self.req_resp-self.req_sent
self.part_timeout_factor = Resource.PART_TIMEOUT_FACTOR_AFTER_RTT
if self.rtt == None: if self.rtt == None:
self.rtt = rtt self.rtt = self.link.rtt
self.watchdog_job() self.watchdog_job()
elif self.rtt < rtt: elif rtt < self.rtt:
self.rtt = rtt self.rtt = max(self.rtt - self.rtt*0.05, rtt)
elif rtt > self.rtt:
self.rtt = min(self.rtt + self.rtt*0.05, rtt)
if not self.status == Resource.FAILED: if not self.status == Resource.FAILED:
self.status = Resource.TRANSFERRING self.status = Resource.TRANSFERRING
@@ -574,14 +595,21 @@ class Resource:
self.consecutive_completed_height = cp self.consecutive_completed_height = cp
cp += 1 cp += 1
if self.__progress_callback != None:
self.__progress_callback(self)
# TODO: Remove debug info
# RNS.log("outstanding_parts "+str(self.outstanding_parts))
# RNS.log("total_parts "+str(self.total_parts))
# RNS.log("received_count "+str(self.received_count))
i += 1 i += 1
self.receiving_part = False self.receiving_part = False
if self.__progress_callback != None: # TODO: Remove
self.__progress_callback(self) #if self.outstanding_parts == 0 and self.received_count == self.total_parts:
if self.received_count == self.total_parts:
if self.outstanding_parts == 0 and self.received_count == self.total_parts:
self.assemble() self.assemble()
elif self.outstanding_parts == 0: elif self.outstanding_parts == 0:
# TODO: Figure out if there is a mathematically # TODO: Figure out if there is a mathematically
@@ -755,7 +783,7 @@ class Resource:
def progress_callback(self, callback): def progress_callback(self, callback):
self.__progress_callback = callback self.__progress_callback = callback
def progress(self): def get_progress(self):
""" """
:returns: The current progress of the resource transfer as a *float* between 0.0 and 1.0. :returns: The current progress of the resource transfer as a *float* between 0.0 and 1.0.
""" """
@@ -780,9 +808,12 @@ class Resource:
class ResourceAdvertisement: class ResourceAdvertisement:
HASHMAP_MAX_LEN = 70 OVERHEAD = 128
HASHMAP_MAX_LEN = math.floor((RNS.Link.MDU-OVERHEAD)/Resource.MAPHASH_LEN)
COLLISION_GUARD_SIZE = 2*Resource.WINDOW_MAX+HASHMAP_MAX_LEN COLLISION_GUARD_SIZE = 2*Resource.WINDOW_MAX+HASHMAP_MAX_LEN
assert HASHMAP_MAX_LEN > 0, "The configured MTU is too small to include any map hashes in resource advertisments"
@staticmethod @staticmethod
def is_request(advertisement_packet): def is_request(advertisement_packet):
adv = ResourceAdvertisement.unpack(advertisement_packet.plaintext) adv = ResourceAdvertisement.unpack(advertisement_packet.plaintext)
+19 -41
View File
@@ -36,15 +36,26 @@ class Reticulum:
other programs to use on demand. other programs to use on demand.
""" """
# The default RNS MTU is 500 bytes. This number has been chosen as # Future minimum will probably be locked in at 244 bytes to support
# a balance between compatibility with existing hardware devices # networks with segments of different MTUs. Absolute minimum is 211.
# on one hand, and the ability to use sufficiently high cryptographic
# key sizes on the other. In custom RNS network implementations, it
# is possible to raise this value, but doing so will completely break
# compatibility with all other RNS networks. An identical MTU is a
# prerequisite for peers to communicate in the same network.
MTU = 500 MTU = 500
HEADER_MAXSIZE = 23 """
The MTU that Reticulum adheres to, and will expect other peers to
adhere to. By default, the MTU is 500 bytes. In custom RNS network
implementations, it is possible to change this value, but doing so will
completely break compatibility with all other RNS networks. An identical
MTU is a prerequisite for peers to communicate in the same network.
Unless you really know what you are doing, the MTU should be left at
the default value.
"""
# Length of truncated hashes in bits.
TRUNCATED_HASHLENGTH = 80
HEADER_MINSIZE = 2+1+(TRUNCATED_HASHLENGTH//8)*1
HEADER_MAXSIZE = 2+1+(TRUNCATED_HASHLENGTH//8)*2
MDU = MTU - HEADER_MAXSIZE MDU = MTU - HEADER_MAXSIZE
router = None router = None
@@ -84,7 +95,6 @@ class Reticulum:
Reticulum.cachepath = Reticulum.configdir+"/storage/cache" Reticulum.cachepath = Reticulum.configdir+"/storage/cache"
Reticulum.resourcepath = Reticulum.configdir+"/storage/resources" Reticulum.resourcepath = Reticulum.configdir+"/storage/resources"
Reticulum.__allow_unencrypted = False
Reticulum.__transport_enabled = False Reticulum.__transport_enabled = False
Reticulum.__use_implicit_proof = True Reticulum.__use_implicit_proof = True
@@ -191,20 +201,6 @@ class Reticulum:
Reticulum.__use_implicit_proof = True Reticulum.__use_implicit_proof = True
if v == False: if v == False:
Reticulum.__use_implicit_proof = False Reticulum.__use_implicit_proof = False
if option == "allow_unencrypted":
v = self.config["reticulum"].as_bool(option)
if v == True:
RNS.log("", RNS.LOG_CRITICAL)
RNS.log("! ! ! ! ! ! ! ! !", RNS.LOG_CRITICAL)
RNS.log("", RNS.LOG_CRITICAL)
RNS.log("Danger! Encryptionless links have been allowed in the config file!", RNS.LOG_CRITICAL)
RNS.log("Beware of the consequences! Any data sent over a link can potentially be intercepted,", RNS.LOG_CRITICAL)
RNS.log("read and modified! If you are not absolutely sure that you want this,", RNS.LOG_CRITICAL)
RNS.log("you should exit Reticulum NOW and change your config file!", RNS.LOG_CRITICAL)
RNS.log("", RNS.LOG_CRITICAL)
RNS.log("! ! ! ! ! ! ! ! !", RNS.LOG_CRITICAL)
RNS.log("", RNS.LOG_CRITICAL)
Reticulum.__allow_unencrypted = True
self.__start_local_interface() self.__start_local_interface()
@@ -455,16 +451,6 @@ class Reticulum:
self.config.write() self.config.write()
self.__apply_config() self.__apply_config()
@staticmethod
def should_allow_unencrypted():
"""
Returns whether unencrypted links are allowed by the
current configuration.
:returns: True if the current running configuration allows downgrading links to plaintext. False if not.
"""
return Reticulum.__allow_unencrypted
@staticmethod @staticmethod
def should_use_implicit_proof(): def should_use_implicit_proof():
""" """
@@ -495,14 +481,6 @@ __default_rns_config__ = '''# This is the default Reticulum config file.
[reticulum] [reticulum]
# Don't allow unencrypted links by default.
# If you REALLY need to allow unencrypted links, for example
# for debug or regulatory purposes, this can be set to true.
# This directive is optional and can be removed for brevity.
allow_unencrypted = False
# If you enable Transport, your system will route traffic # If you enable Transport, your system will route traffic
# for other peers, pass announces and serve path requests. # for other peers, pass announces and serve path requests.
# This should be done for systems that are suited to act # This should be done for systems that are suited to act
+6 -4
View File
@@ -9,6 +9,10 @@ from time import sleep
from .vendor import umsgpack as umsgpack from .vendor import umsgpack as umsgpack
class Transport: class Transport:
"""
Through static methods of this class you can interact with Reticulums
Transport system.
"""
# Constants # Constants
BROADCAST = 0x00; BROADCAST = 0x00;
TRANSPORT = 0x01; TRANSPORT = 0x01;
@@ -521,13 +525,10 @@ class Transport:
# accordingly if we are. # accordingly if we are.
if packet.transport_id != None and packet.packet_type != RNS.Packet.ANNOUNCE: if packet.transport_id != None and packet.packet_type != RNS.Packet.ANNOUNCE:
if packet.transport_id == Transport.identity.hash: if packet.transport_id == Transport.identity.hash:
# TODO: Remove at some point
# RNS.log("Received packet in transport for "+RNS.prettyhexrep(packet.destination_hash)+" with matching transport ID, transporting it...", RNS.LOG_DEBUG)
if packet.destination_hash in Transport.destination_table: if packet.destination_hash in Transport.destination_table:
next_hop = Transport.destination_table[packet.destination_hash][1] next_hop = Transport.destination_table[packet.destination_hash][1]
remaining_hops = Transport.destination_table[packet.destination_hash][2] remaining_hops = Transport.destination_table[packet.destination_hash][2]
# TODO: Remove at some point
# RNS.log("Next hop to destination is "+RNS.prettyhexrep(next_hop)+" with "+str(remaining_hops)+" hops remaining, transporting it.", RNS.LOG_DEBUG)
if remaining_hops > 1: if remaining_hops > 1:
# Just increase hop count and transmit # Just increase hop count and transmit
new_raw = packet.raw[0:1] new_raw = packet.raw[0:1]
@@ -892,6 +893,7 @@ class Transport:
receipt_validated = receipt.validate_proof_packet(packet) receipt_validated = receipt.validate_proof_packet(packet)
if receipt_validated: if receipt_validated:
if receipt in Transport.receipts:
Transport.receipts.remove(receipt) Transport.receipts.remove(receipt)
Transport.jobs_locked = False Transport.jobs_locked = False
+1 -1
View File
@@ -9,7 +9,7 @@ from ._version import __version__
from .Reticulum import Reticulum from .Reticulum import Reticulum
from .Identity import Identity from .Identity import Identity
from .Link import Link from .Link import Link, RequestReceipt
from .Transport import Transport from .Transport import Transport
from .Destination import Destination from .Destination import Destination
from .Packet import Packet from .Packet import Packet
+1 -1
View File
@@ -1 +1 @@
__version__ = "0.2.3" __version__ = "0.2.4"
+1 -1
View File
@@ -19,7 +19,7 @@ import sys
from codecs import BOM_UTF8, BOM_UTF16, BOM_UTF16_BE, BOM_UTF16_LE from codecs import BOM_UTF8, BOM_UTF16, BOM_UTF16_BE, BOM_UTF16_LE
import six import RNS.vendor.six as six
__version__ = '5.0.6' __version__ = '5.0.6'
# imported lazily to avoid startup performance hit if it isn't used # imported lazily to avoid startup performance hit if it isn't used
+998
View File
@@ -0,0 +1,998 @@
# Copyright (c) 2010-2020 Benjamin Peterson
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in all
# copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
"""Utilities for writing code that runs on Python 2 and 3"""
from __future__ import absolute_import
import functools
import itertools
import operator
import sys
import types
__author__ = "Benjamin Peterson <benjamin@python.org>"
__version__ = "1.16.0"
# Useful for very coarse version differentiation.
PY2 = sys.version_info[0] == 2
PY3 = sys.version_info[0] == 3
PY34 = sys.version_info[0:2] >= (3, 4)
if PY3:
string_types = str,
integer_types = int,
class_types = type,
text_type = str
binary_type = bytes
MAXSIZE = sys.maxsize
else:
string_types = basestring,
integer_types = (int, long)
class_types = (type, types.ClassType)
text_type = unicode
binary_type = str
if sys.platform.startswith("java"):
# Jython always uses 32 bits.
MAXSIZE = int((1 << 31) - 1)
else:
# It's possible to have sizeof(long) != sizeof(Py_ssize_t).
class X(object):
def __len__(self):
return 1 << 31
try:
len(X())
except OverflowError:
# 32-bit
MAXSIZE = int((1 << 31) - 1)
else:
# 64-bit
MAXSIZE = int((1 << 63) - 1)
del X
if PY34:
from importlib.util import spec_from_loader
else:
spec_from_loader = None
def _add_doc(func, doc):
"""Add documentation to a function."""
func.__doc__ = doc
def _import_module(name):
"""Import module, returning the module after the last dot."""
__import__(name)
return sys.modules[name]
class _LazyDescr(object):
def __init__(self, name):
self.name = name
def __get__(self, obj, tp):
result = self._resolve()
setattr(obj, self.name, result) # Invokes __set__.
try:
# This is a bit ugly, but it avoids running this again by
# removing this descriptor.
delattr(obj.__class__, self.name)
except AttributeError:
pass
return result
class MovedModule(_LazyDescr):
def __init__(self, name, old, new=None):
super(MovedModule, self).__init__(name)
if PY3:
if new is None:
new = name
self.mod = new
else:
self.mod = old
def _resolve(self):
return _import_module(self.mod)
def __getattr__(self, attr):
_module = self._resolve()
value = getattr(_module, attr)
setattr(self, attr, value)
return value
class _LazyModule(types.ModuleType):
def __init__(self, name):
super(_LazyModule, self).__init__(name)
self.__doc__ = self.__class__.__doc__
def __dir__(self):
attrs = ["__doc__", "__name__"]
attrs += [attr.name for attr in self._moved_attributes]
return attrs
# Subclasses should override this
_moved_attributes = []
class MovedAttribute(_LazyDescr):
def __init__(self, name, old_mod, new_mod, old_attr=None, new_attr=None):
super(MovedAttribute, self).__init__(name)
if PY3:
if new_mod is None:
new_mod = name
self.mod = new_mod
if new_attr is None:
if old_attr is None:
new_attr = name
else:
new_attr = old_attr
self.attr = new_attr
else:
self.mod = old_mod
if old_attr is None:
old_attr = name
self.attr = old_attr
def _resolve(self):
module = _import_module(self.mod)
return getattr(module, self.attr)
class _SixMetaPathImporter(object):
"""
A meta path importer to import six.moves and its submodules.
This class implements a PEP302 finder and loader. It should be compatible
with Python 2.5 and all existing versions of Python3
"""
def __init__(self, six_module_name):
self.name = six_module_name
self.known_modules = {}
def _add_module(self, mod, *fullnames):
for fullname in fullnames:
self.known_modules[self.name + "." + fullname] = mod
def _get_module(self, fullname):
return self.known_modules[self.name + "." + fullname]
def find_module(self, fullname, path=None):
if fullname in self.known_modules:
return self
return None
def find_spec(self, fullname, path, target=None):
if fullname in self.known_modules:
return spec_from_loader(fullname, self)
return None
def __get_module(self, fullname):
try:
return self.known_modules[fullname]
except KeyError:
raise ImportError("This loader does not know module " + fullname)
def load_module(self, fullname):
try:
# in case of a reload
return sys.modules[fullname]
except KeyError:
pass
mod = self.__get_module(fullname)
if isinstance(mod, MovedModule):
mod = mod._resolve()
else:
mod.__loader__ = self
sys.modules[fullname] = mod
return mod
def is_package(self, fullname):
"""
Return true, if the named module is a package.
We need this method to get correct spec objects with
Python 3.4 (see PEP451)
"""
return hasattr(self.__get_module(fullname), "__path__")
def get_code(self, fullname):
"""Return None
Required, if is_package is implemented"""
self.__get_module(fullname) # eventually raises ImportError
return None
get_source = get_code # same as get_code
def create_module(self, spec):
return self.load_module(spec.name)
def exec_module(self, module):
pass
_importer = _SixMetaPathImporter(__name__)
class _MovedItems(_LazyModule):
"""Lazy loading of moved objects"""
__path__ = [] # mark as package
_moved_attributes = [
MovedAttribute("cStringIO", "cStringIO", "io", "StringIO"),
MovedAttribute("filter", "itertools", "builtins", "ifilter", "filter"),
MovedAttribute("filterfalse", "itertools", "itertools", "ifilterfalse", "filterfalse"),
MovedAttribute("input", "__builtin__", "builtins", "raw_input", "input"),
MovedAttribute("intern", "__builtin__", "sys"),
MovedAttribute("map", "itertools", "builtins", "imap", "map"),
MovedAttribute("getcwd", "os", "os", "getcwdu", "getcwd"),
MovedAttribute("getcwdb", "os", "os", "getcwd", "getcwdb"),
MovedAttribute("getoutput", "commands", "subprocess"),
MovedAttribute("range", "__builtin__", "builtins", "xrange", "range"),
MovedAttribute("reload_module", "__builtin__", "importlib" if PY34 else "imp", "reload"),
MovedAttribute("reduce", "__builtin__", "functools"),
MovedAttribute("shlex_quote", "pipes", "shlex", "quote"),
MovedAttribute("StringIO", "StringIO", "io"),
MovedAttribute("UserDict", "UserDict", "collections"),
MovedAttribute("UserList", "UserList", "collections"),
MovedAttribute("UserString", "UserString", "collections"),
MovedAttribute("xrange", "__builtin__", "builtins", "xrange", "range"),
MovedAttribute("zip", "itertools", "builtins", "izip", "zip"),
MovedAttribute("zip_longest", "itertools", "itertools", "izip_longest", "zip_longest"),
MovedModule("builtins", "__builtin__"),
MovedModule("configparser", "ConfigParser"),
MovedModule("collections_abc", "collections", "collections.abc" if sys.version_info >= (3, 3) else "collections"),
MovedModule("copyreg", "copy_reg"),
MovedModule("dbm_gnu", "gdbm", "dbm.gnu"),
MovedModule("dbm_ndbm", "dbm", "dbm.ndbm"),
MovedModule("_dummy_thread", "dummy_thread", "_dummy_thread" if sys.version_info < (3, 9) else "_thread"),
MovedModule("http_cookiejar", "cookielib", "http.cookiejar"),
MovedModule("http_cookies", "Cookie", "http.cookies"),
MovedModule("html_entities", "htmlentitydefs", "html.entities"),
MovedModule("html_parser", "HTMLParser", "html.parser"),
MovedModule("http_client", "httplib", "http.client"),
MovedModule("email_mime_base", "email.MIMEBase", "email.mime.base"),
MovedModule("email_mime_image", "email.MIMEImage", "email.mime.image"),
MovedModule("email_mime_multipart", "email.MIMEMultipart", "email.mime.multipart"),
MovedModule("email_mime_nonmultipart", "email.MIMENonMultipart", "email.mime.nonmultipart"),
MovedModule("email_mime_text", "email.MIMEText", "email.mime.text"),
MovedModule("BaseHTTPServer", "BaseHTTPServer", "http.server"),
MovedModule("CGIHTTPServer", "CGIHTTPServer", "http.server"),
MovedModule("SimpleHTTPServer", "SimpleHTTPServer", "http.server"),
MovedModule("cPickle", "cPickle", "pickle"),
MovedModule("queue", "Queue"),
MovedModule("reprlib", "repr"),
MovedModule("socketserver", "SocketServer"),
MovedModule("_thread", "thread", "_thread"),
MovedModule("tkinter", "Tkinter"),
MovedModule("tkinter_dialog", "Dialog", "tkinter.dialog"),
MovedModule("tkinter_filedialog", "FileDialog", "tkinter.filedialog"),
MovedModule("tkinter_scrolledtext", "ScrolledText", "tkinter.scrolledtext"),
MovedModule("tkinter_simpledialog", "SimpleDialog", "tkinter.simpledialog"),
MovedModule("tkinter_tix", "Tix", "tkinter.tix"),
MovedModule("tkinter_ttk", "ttk", "tkinter.ttk"),
MovedModule("tkinter_constants", "Tkconstants", "tkinter.constants"),
MovedModule("tkinter_dnd", "Tkdnd", "tkinter.dnd"),
MovedModule("tkinter_colorchooser", "tkColorChooser",
"tkinter.colorchooser"),
MovedModule("tkinter_commondialog", "tkCommonDialog",
"tkinter.commondialog"),
MovedModule("tkinter_tkfiledialog", "tkFileDialog", "tkinter.filedialog"),
MovedModule("tkinter_font", "tkFont", "tkinter.font"),
MovedModule("tkinter_messagebox", "tkMessageBox", "tkinter.messagebox"),
MovedModule("tkinter_tksimpledialog", "tkSimpleDialog",
"tkinter.simpledialog"),
MovedModule("urllib_parse", __name__ + ".moves.urllib_parse", "urllib.parse"),
MovedModule("urllib_error", __name__ + ".moves.urllib_error", "urllib.error"),
MovedModule("urllib", __name__ + ".moves.urllib", __name__ + ".moves.urllib"),
MovedModule("urllib_robotparser", "robotparser", "urllib.robotparser"),
MovedModule("xmlrpc_client", "xmlrpclib", "xmlrpc.client"),
MovedModule("xmlrpc_server", "SimpleXMLRPCServer", "xmlrpc.server"),
]
# Add windows specific modules.
if sys.platform == "win32":
_moved_attributes += [
MovedModule("winreg", "_winreg"),
]
for attr in _moved_attributes:
setattr(_MovedItems, attr.name, attr)
if isinstance(attr, MovedModule):
_importer._add_module(attr, "moves." + attr.name)
del attr
_MovedItems._moved_attributes = _moved_attributes
moves = _MovedItems(__name__ + ".moves")
_importer._add_module(moves, "moves")
class Module_six_moves_urllib_parse(_LazyModule):
"""Lazy loading of moved objects in six.moves.urllib_parse"""
_urllib_parse_moved_attributes = [
MovedAttribute("ParseResult", "urlparse", "urllib.parse"),
MovedAttribute("SplitResult", "urlparse", "urllib.parse"),
MovedAttribute("parse_qs", "urlparse", "urllib.parse"),
MovedAttribute("parse_qsl", "urlparse", "urllib.parse"),
MovedAttribute("urldefrag", "urlparse", "urllib.parse"),
MovedAttribute("urljoin", "urlparse", "urllib.parse"),
MovedAttribute("urlparse", "urlparse", "urllib.parse"),
MovedAttribute("urlsplit", "urlparse", "urllib.parse"),
MovedAttribute("urlunparse", "urlparse", "urllib.parse"),
MovedAttribute("urlunsplit", "urlparse", "urllib.parse"),
MovedAttribute("quote", "urllib", "urllib.parse"),
MovedAttribute("quote_plus", "urllib", "urllib.parse"),
MovedAttribute("unquote", "urllib", "urllib.parse"),
MovedAttribute("unquote_plus", "urllib", "urllib.parse"),
MovedAttribute("unquote_to_bytes", "urllib", "urllib.parse", "unquote", "unquote_to_bytes"),
MovedAttribute("urlencode", "urllib", "urllib.parse"),
MovedAttribute("splitquery", "urllib", "urllib.parse"),
MovedAttribute("splittag", "urllib", "urllib.parse"),
MovedAttribute("splituser", "urllib", "urllib.parse"),
MovedAttribute("splitvalue", "urllib", "urllib.parse"),
MovedAttribute("uses_fragment", "urlparse", "urllib.parse"),
MovedAttribute("uses_netloc", "urlparse", "urllib.parse"),
MovedAttribute("uses_params", "urlparse", "urllib.parse"),
MovedAttribute("uses_query", "urlparse", "urllib.parse"),
MovedAttribute("uses_relative", "urlparse", "urllib.parse"),
]
for attr in _urllib_parse_moved_attributes:
setattr(Module_six_moves_urllib_parse, attr.name, attr)
del attr
Module_six_moves_urllib_parse._moved_attributes = _urllib_parse_moved_attributes
_importer._add_module(Module_six_moves_urllib_parse(__name__ + ".moves.urllib_parse"),
"moves.urllib_parse", "moves.urllib.parse")
class Module_six_moves_urllib_error(_LazyModule):
"""Lazy loading of moved objects in six.moves.urllib_error"""
_urllib_error_moved_attributes = [
MovedAttribute("URLError", "urllib2", "urllib.error"),
MovedAttribute("HTTPError", "urllib2", "urllib.error"),
MovedAttribute("ContentTooShortError", "urllib", "urllib.error"),
]
for attr in _urllib_error_moved_attributes:
setattr(Module_six_moves_urllib_error, attr.name, attr)
del attr
Module_six_moves_urllib_error._moved_attributes = _urllib_error_moved_attributes
_importer._add_module(Module_six_moves_urllib_error(__name__ + ".moves.urllib.error"),
"moves.urllib_error", "moves.urllib.error")
class Module_six_moves_urllib_request(_LazyModule):
"""Lazy loading of moved objects in six.moves.urllib_request"""
_urllib_request_moved_attributes = [
MovedAttribute("urlopen", "urllib2", "urllib.request"),
MovedAttribute("install_opener", "urllib2", "urllib.request"),
MovedAttribute("build_opener", "urllib2", "urllib.request"),
MovedAttribute("pathname2url", "urllib", "urllib.request"),
MovedAttribute("url2pathname", "urllib", "urllib.request"),
MovedAttribute("getproxies", "urllib", "urllib.request"),
MovedAttribute("Request", "urllib2", "urllib.request"),
MovedAttribute("OpenerDirector", "urllib2", "urllib.request"),
MovedAttribute("HTTPDefaultErrorHandler", "urllib2", "urllib.request"),
MovedAttribute("HTTPRedirectHandler", "urllib2", "urllib.request"),
MovedAttribute("HTTPCookieProcessor", "urllib2", "urllib.request"),
MovedAttribute("ProxyHandler", "urllib2", "urllib.request"),
MovedAttribute("BaseHandler", "urllib2", "urllib.request"),
MovedAttribute("HTTPPasswordMgr", "urllib2", "urllib.request"),
MovedAttribute("HTTPPasswordMgrWithDefaultRealm", "urllib2", "urllib.request"),
MovedAttribute("AbstractBasicAuthHandler", "urllib2", "urllib.request"),
MovedAttribute("HTTPBasicAuthHandler", "urllib2", "urllib.request"),
MovedAttribute("ProxyBasicAuthHandler", "urllib2", "urllib.request"),
MovedAttribute("AbstractDigestAuthHandler", "urllib2", "urllib.request"),
MovedAttribute("HTTPDigestAuthHandler", "urllib2", "urllib.request"),
MovedAttribute("ProxyDigestAuthHandler", "urllib2", "urllib.request"),
MovedAttribute("HTTPHandler", "urllib2", "urllib.request"),
MovedAttribute("HTTPSHandler", "urllib2", "urllib.request"),
MovedAttribute("FileHandler", "urllib2", "urllib.request"),
MovedAttribute("FTPHandler", "urllib2", "urllib.request"),
MovedAttribute("CacheFTPHandler", "urllib2", "urllib.request"),
MovedAttribute("UnknownHandler", "urllib2", "urllib.request"),
MovedAttribute("HTTPErrorProcessor", "urllib2", "urllib.request"),
MovedAttribute("urlretrieve", "urllib", "urllib.request"),
MovedAttribute("urlcleanup", "urllib", "urllib.request"),
MovedAttribute("URLopener", "urllib", "urllib.request"),
MovedAttribute("FancyURLopener", "urllib", "urllib.request"),
MovedAttribute("proxy_bypass", "urllib", "urllib.request"),
MovedAttribute("parse_http_list", "urllib2", "urllib.request"),
MovedAttribute("parse_keqv_list", "urllib2", "urllib.request"),
]
for attr in _urllib_request_moved_attributes:
setattr(Module_six_moves_urllib_request, attr.name, attr)
del attr
Module_six_moves_urllib_request._moved_attributes = _urllib_request_moved_attributes
_importer._add_module(Module_six_moves_urllib_request(__name__ + ".moves.urllib.request"),
"moves.urllib_request", "moves.urllib.request")
class Module_six_moves_urllib_response(_LazyModule):
"""Lazy loading of moved objects in six.moves.urllib_response"""
_urllib_response_moved_attributes = [
MovedAttribute("addbase", "urllib", "urllib.response"),
MovedAttribute("addclosehook", "urllib", "urllib.response"),
MovedAttribute("addinfo", "urllib", "urllib.response"),
MovedAttribute("addinfourl", "urllib", "urllib.response"),
]
for attr in _urllib_response_moved_attributes:
setattr(Module_six_moves_urllib_response, attr.name, attr)
del attr
Module_six_moves_urllib_response._moved_attributes = _urllib_response_moved_attributes
_importer._add_module(Module_six_moves_urllib_response(__name__ + ".moves.urllib.response"),
"moves.urllib_response", "moves.urllib.response")
class Module_six_moves_urllib_robotparser(_LazyModule):
"""Lazy loading of moved objects in six.moves.urllib_robotparser"""
_urllib_robotparser_moved_attributes = [
MovedAttribute("RobotFileParser", "robotparser", "urllib.robotparser"),
]
for attr in _urllib_robotparser_moved_attributes:
setattr(Module_six_moves_urllib_robotparser, attr.name, attr)
del attr
Module_six_moves_urllib_robotparser._moved_attributes = _urllib_robotparser_moved_attributes
_importer._add_module(Module_six_moves_urllib_robotparser(__name__ + ".moves.urllib.robotparser"),
"moves.urllib_robotparser", "moves.urllib.robotparser")
class Module_six_moves_urllib(types.ModuleType):
"""Create a six.moves.urllib namespace that resembles the Python 3 namespace"""
__path__ = [] # mark as package
parse = _importer._get_module("moves.urllib_parse")
error = _importer._get_module("moves.urllib_error")
request = _importer._get_module("moves.urllib_request")
response = _importer._get_module("moves.urllib_response")
robotparser = _importer._get_module("moves.urllib_robotparser")
def __dir__(self):
return ['parse', 'error', 'request', 'response', 'robotparser']
_importer._add_module(Module_six_moves_urllib(__name__ + ".moves.urllib"),
"moves.urllib")
def add_move(move):
"""Add an item to six.moves."""
setattr(_MovedItems, move.name, move)
def remove_move(name):
"""Remove item from six.moves."""
try:
delattr(_MovedItems, name)
except AttributeError:
try:
del moves.__dict__[name]
except KeyError:
raise AttributeError("no such move, %r" % (name,))
if PY3:
_meth_func = "__func__"
_meth_self = "__self__"
_func_closure = "__closure__"
_func_code = "__code__"
_func_defaults = "__defaults__"
_func_globals = "__globals__"
else:
_meth_func = "im_func"
_meth_self = "im_self"
_func_closure = "func_closure"
_func_code = "func_code"
_func_defaults = "func_defaults"
_func_globals = "func_globals"
try:
advance_iterator = next
except NameError:
def advance_iterator(it):
return it.next()
next = advance_iterator
try:
callable = callable
except NameError:
def callable(obj):
return any("__call__" in klass.__dict__ for klass in type(obj).__mro__)
if PY3:
def get_unbound_function(unbound):
return unbound
create_bound_method = types.MethodType
def create_unbound_method(func, cls):
return func
Iterator = object
else:
def get_unbound_function(unbound):
return unbound.im_func
def create_bound_method(func, obj):
return types.MethodType(func, obj, obj.__class__)
def create_unbound_method(func, cls):
return types.MethodType(func, None, cls)
class Iterator(object):
def next(self):
return type(self).__next__(self)
callable = callable
_add_doc(get_unbound_function,
"""Get the function out of a possibly unbound function""")
get_method_function = operator.attrgetter(_meth_func)
get_method_self = operator.attrgetter(_meth_self)
get_function_closure = operator.attrgetter(_func_closure)
get_function_code = operator.attrgetter(_func_code)
get_function_defaults = operator.attrgetter(_func_defaults)
get_function_globals = operator.attrgetter(_func_globals)
if PY3:
def iterkeys(d, **kw):
return iter(d.keys(**kw))
def itervalues(d, **kw):
return iter(d.values(**kw))
def iteritems(d, **kw):
return iter(d.items(**kw))
def iterlists(d, **kw):
return iter(d.lists(**kw))
viewkeys = operator.methodcaller("keys")
viewvalues = operator.methodcaller("values")
viewitems = operator.methodcaller("items")
else:
def iterkeys(d, **kw):
return d.iterkeys(**kw)
def itervalues(d, **kw):
return d.itervalues(**kw)
def iteritems(d, **kw):
return d.iteritems(**kw)
def iterlists(d, **kw):
return d.iterlists(**kw)
viewkeys = operator.methodcaller("viewkeys")
viewvalues = operator.methodcaller("viewvalues")
viewitems = operator.methodcaller("viewitems")
_add_doc(iterkeys, "Return an iterator over the keys of a dictionary.")
_add_doc(itervalues, "Return an iterator over the values of a dictionary.")
_add_doc(iteritems,
"Return an iterator over the (key, value) pairs of a dictionary.")
_add_doc(iterlists,
"Return an iterator over the (key, [values]) pairs of a dictionary.")
if PY3:
def b(s):
return s.encode("latin-1")
def u(s):
return s
unichr = chr
import struct
int2byte = struct.Struct(">B").pack
del struct
byte2int = operator.itemgetter(0)
indexbytes = operator.getitem
iterbytes = iter
import io
StringIO = io.StringIO
BytesIO = io.BytesIO
del io
_assertCountEqual = "assertCountEqual"
if sys.version_info[1] <= 1:
_assertRaisesRegex = "assertRaisesRegexp"
_assertRegex = "assertRegexpMatches"
_assertNotRegex = "assertNotRegexpMatches"
else:
_assertRaisesRegex = "assertRaisesRegex"
_assertRegex = "assertRegex"
_assertNotRegex = "assertNotRegex"
else:
def b(s):
return s
# Workaround for standalone backslash
def u(s):
return unicode(s.replace(r'\\', r'\\\\'), "unicode_escape")
unichr = unichr
int2byte = chr
def byte2int(bs):
return ord(bs[0])
def indexbytes(buf, i):
return ord(buf[i])
iterbytes = functools.partial(itertools.imap, ord)
import StringIO
StringIO = BytesIO = StringIO.StringIO
_assertCountEqual = "assertItemsEqual"
_assertRaisesRegex = "assertRaisesRegexp"
_assertRegex = "assertRegexpMatches"
_assertNotRegex = "assertNotRegexpMatches"
_add_doc(b, """Byte literal""")
_add_doc(u, """Text literal""")
def assertCountEqual(self, *args, **kwargs):
return getattr(self, _assertCountEqual)(*args, **kwargs)
def assertRaisesRegex(self, *args, **kwargs):
return getattr(self, _assertRaisesRegex)(*args, **kwargs)
def assertRegex(self, *args, **kwargs):
return getattr(self, _assertRegex)(*args, **kwargs)
def assertNotRegex(self, *args, **kwargs):
return getattr(self, _assertNotRegex)(*args, **kwargs)
if PY3:
exec_ = getattr(moves.builtins, "exec")
def reraise(tp, value, tb=None):
try:
if value is None:
value = tp()
if value.__traceback__ is not tb:
raise value.with_traceback(tb)
raise value
finally:
value = None
tb = None
else:
def exec_(_code_, _globs_=None, _locs_=None):
"""Execute code in a namespace."""
if _globs_ is None:
frame = sys._getframe(1)
_globs_ = frame.f_globals
if _locs_ is None:
_locs_ = frame.f_locals
del frame
elif _locs_ is None:
_locs_ = _globs_
exec("""exec _code_ in _globs_, _locs_""")
exec_("""def reraise(tp, value, tb=None):
try:
raise tp, value, tb
finally:
tb = None
""")
if sys.version_info[:2] > (3,):
exec_("""def raise_from(value, from_value):
try:
raise value from from_value
finally:
value = None
""")
else:
def raise_from(value, from_value):
raise value
print_ = getattr(moves.builtins, "print", None)
if print_ is None:
def print_(*args, **kwargs):
"""The new-style print function for Python 2.4 and 2.5."""
fp = kwargs.pop("file", sys.stdout)
if fp is None:
return
def write(data):
if not isinstance(data, basestring):
data = str(data)
# If the file has an encoding, encode unicode with it.
if (isinstance(fp, file) and
isinstance(data, unicode) and
fp.encoding is not None):
errors = getattr(fp, "errors", None)
if errors is None:
errors = "strict"
data = data.encode(fp.encoding, errors)
fp.write(data)
want_unicode = False
sep = kwargs.pop("sep", None)
if sep is not None:
if isinstance(sep, unicode):
want_unicode = True
elif not isinstance(sep, str):
raise TypeError("sep must be None or a string")
end = kwargs.pop("end", None)
if end is not None:
if isinstance(end, unicode):
want_unicode = True
elif not isinstance(end, str):
raise TypeError("end must be None or a string")
if kwargs:
raise TypeError("invalid keyword arguments to print()")
if not want_unicode:
for arg in args:
if isinstance(arg, unicode):
want_unicode = True
break
if want_unicode:
newline = unicode("\n")
space = unicode(" ")
else:
newline = "\n"
space = " "
if sep is None:
sep = space
if end is None:
end = newline
for i, arg in enumerate(args):
if i:
write(sep)
write(arg)
write(end)
if sys.version_info[:2] < (3, 3):
_print = print_
def print_(*args, **kwargs):
fp = kwargs.get("file", sys.stdout)
flush = kwargs.pop("flush", False)
_print(*args, **kwargs)
if flush and fp is not None:
fp.flush()
_add_doc(reraise, """Reraise an exception.""")
if sys.version_info[0:2] < (3, 4):
# This does exactly the same what the :func:`py3:functools.update_wrapper`
# function does on Python versions after 3.2. It sets the ``__wrapped__``
# attribute on ``wrapper`` object and it doesn't raise an error if any of
# the attributes mentioned in ``assigned`` and ``updated`` are missing on
# ``wrapped`` object.
def _update_wrapper(wrapper, wrapped,
assigned=functools.WRAPPER_ASSIGNMENTS,
updated=functools.WRAPPER_UPDATES):
for attr in assigned:
try:
value = getattr(wrapped, attr)
except AttributeError:
continue
else:
setattr(wrapper, attr, value)
for attr in updated:
getattr(wrapper, attr).update(getattr(wrapped, attr, {}))
wrapper.__wrapped__ = wrapped
return wrapper
_update_wrapper.__doc__ = functools.update_wrapper.__doc__
def wraps(wrapped, assigned=functools.WRAPPER_ASSIGNMENTS,
updated=functools.WRAPPER_UPDATES):
return functools.partial(_update_wrapper, wrapped=wrapped,
assigned=assigned, updated=updated)
wraps.__doc__ = functools.wraps.__doc__
else:
wraps = functools.wraps
def with_metaclass(meta, *bases):
"""Create a base class with a metaclass."""
# This requires a bit of explanation: the basic idea is to make a dummy
# metaclass for one level of class instantiation that replaces itself with
# the actual metaclass.
class metaclass(type):
def __new__(cls, name, this_bases, d):
if sys.version_info[:2] >= (3, 7):
# This version introduced PEP 560 that requires a bit
# of extra care (we mimic what is done by __build_class__).
resolved_bases = types.resolve_bases(bases)
if resolved_bases is not bases:
d['__orig_bases__'] = bases
else:
resolved_bases = bases
return meta(name, resolved_bases, d)
@classmethod
def __prepare__(cls, name, this_bases):
return meta.__prepare__(name, bases)
return type.__new__(metaclass, 'temporary_class', (), {})
def add_metaclass(metaclass):
"""Class decorator for creating a class with a metaclass."""
def wrapper(cls):
orig_vars = cls.__dict__.copy()
slots = orig_vars.get('__slots__')
if slots is not None:
if isinstance(slots, str):
slots = [slots]
for slots_var in slots:
orig_vars.pop(slots_var)
orig_vars.pop('__dict__', None)
orig_vars.pop('__weakref__', None)
if hasattr(cls, '__qualname__'):
orig_vars['__qualname__'] = cls.__qualname__
return metaclass(cls.__name__, cls.__bases__, orig_vars)
return wrapper
def ensure_binary(s, encoding='utf-8', errors='strict'):
"""Coerce **s** to six.binary_type.
For Python 2:
- `unicode` -> encoded to `str`
- `str` -> `str`
For Python 3:
- `str` -> encoded to `bytes`
- `bytes` -> `bytes`
"""
if isinstance(s, binary_type):
return s
if isinstance(s, text_type):
return s.encode(encoding, errors)
raise TypeError("not expecting type '%s'" % type(s))
def ensure_str(s, encoding='utf-8', errors='strict'):
"""Coerce *s* to `str`.
For Python 2:
- `unicode` -> encoded to `str`
- `str` -> `str`
For Python 3:
- `str` -> `str`
- `bytes` -> decoded to `str`
"""
# Optimization: Fast return for the common case.
if type(s) is str:
return s
if PY2 and isinstance(s, text_type):
return s.encode(encoding, errors)
elif PY3 and isinstance(s, binary_type):
return s.decode(encoding, errors)
elif not isinstance(s, (text_type, binary_type)):
raise TypeError("not expecting type '%s'" % type(s))
return s
def ensure_text(s, encoding='utf-8', errors='strict'):
"""Coerce *s* to six.text_type.
For Python 2:
- `unicode` -> `unicode`
- `str` -> `unicode`
For Python 3:
- `str` -> `str`
- `bytes` -> decoded to `str`
"""
if isinstance(s, binary_type):
return s.decode(encoding, errors)
elif isinstance(s, text_type):
return s
else:
raise TypeError("not expecting type '%s'" % type(s))
def python_2_unicode_compatible(klass):
"""
A class decorator that defines __unicode__ and __str__ methods under Python 2.
Under Python 3 it does nothing.
To support Python 2 and 3 with a single code base, define a __str__ method
returning text and apply this decorator to the class.
"""
if PY2:
if '__str__' not in klass.__dict__:
raise ValueError("@python_2_unicode_compatible cannot be applied "
"to %s because it doesn't define __str__()." %
klass.__name__)
klass.__unicode__ = klass.__str__
klass.__str__ = lambda self: self.__unicode__().encode('utf-8')
return klass
# Complete the moves implementation.
# This code is at the end of this module to speed up module loading.
# Turn this module into a package.
__path__ = [] # required for PEP 302 and PEP 451
__package__ = __name__ # see PEP 366 @ReservedAssignment
if globals().get("__spec__") is not None:
__spec__.submodule_search_locations = [] # PEP 451 @UndefinedVariable
# Remove other six meta path importers, since they cause problems. This can
# happen if six is removed from sys.modules and then reloaded. (Setuptools does
# this for some reason.)
if sys.meta_path:
for i, importer in enumerate(sys.meta_path):
# Here's some real nastiness: Another "instance" of the six module might
# be floating around. Therefore, we can't use isinstance() to check for
# the six meta path importer, since the other six instance will have
# inserted an importer with different class.
if (type(importer).__name__ == "_SixMetaPathImporter" and
importer.name == __name__):
del sys.meta_path[i]
break
del i, importer
# Finally, add the importer to the meta path import hook.
sys.meta_path.append(_importer)
Binary file not shown.
+1 -1
View File
@@ -1,4 +1,4 @@
# Sphinx build info version 1 # Sphinx build info version 1
# This file hashes the configuration used when building these files. When it is not found, a full rebuild will be done. # This file hashes the configuration used when building these files. When it is not found, a full rebuild will be done.
config: 75fee65d4971d4f4b61034cb277ccd5b config: eda3a1317314f558917722e3479f8836
tags: 645f666f9bcd5a90fca523b33c5a78b7 tags: 645f666f9bcd5a90fca523b33c5a78b7
+12 -4
View File
@@ -39,7 +39,7 @@ Destination
Packet Packet
------ ------
.. autoclass:: RNS.Packet .. autoclass:: RNS.Packet(destination, data, create_receipt = True)
:members: :members:
.. _api-packetreceipt: .. _api-packetreceipt:
@@ -47,7 +47,7 @@ Packet
Packet Receipt Packet Receipt
-------------- --------------
.. autoclass:: RNS.PacketReceipt .. autoclass:: RNS.PacketReceipt()
:members: :members:
.. _api-link: .. _api-link:
@@ -55,7 +55,15 @@ Packet Receipt
Link Link
---- ----
.. autoclass:: RNS.Link .. autoclass:: RNS.Link(destination, established_callback=None, closed_callback = None)
:members:
.. _api-requestreceipt:
Request Receipt
---------------
.. autoclass:: RNS.RequestReceipt()
:members: :members:
.. _api-resource: .. _api-resource:
@@ -63,7 +71,7 @@ Link
Resource Resource
-------- --------
.. autoclass:: RNS.Resource .. autoclass:: RNS.Resource(data, link, advertise=True, auto_compress=True, callback=None, progress_callback=None, timeout=None)
:members: :members:
.. _api-transport: .. _api-transport:
+2 -2
View File
@@ -429,7 +429,7 @@ terms of bandwidth, so it can be used just for a short exchange, and then recrea
also rotate encryption keys. The link can also be kept alive for longer periods of time, if this is also rotate encryption keys. The link can also be kept alive for longer periods of time, if this is
more suitable to the application. The procedure also inserts the *link id* , a hash calculated from the link request packet, into the memory of forwarding nodes, which means that the communicating nodes can thereafter reach each other simply by referring to this *link id*. more suitable to the application. The procedure also inserts the *link id* , a hash calculated from the link request packet, into the memory of forwarding nodes, which means that the communicating nodes can thereafter reach each other simply by referring to this *link id*.
The combined bandwidth cost of setting up a link is 3 packets totalling 240 bytes (more info in the The combined bandwidth cost of setting up a link is 3 packets totalling 237 bytes (more info in the
:ref:`Binary Packet Format<understanding-packetformat>` section). The amount of bandwidth used on keeping :ref:`Binary Packet Format<understanding-packetformat>` section). The amount of bandwidth used on keeping
a link open is practically negligible, at 0.62 bits per second. Even on a slow 1200 bits per second packet a link open is practically negligible, at 0.62 bits per second. Even on a slow 1200 bits per second packet
radio channel, 100 concurrent links will still leave 95% channel capacity for actual data. radio channel, 100 concurrent links will still leave 95% channel capacity for actual data.
@@ -701,5 +701,5 @@ Binary Packet Format
- Announce : 151 bytes - Announce : 151 bytes
- Link Request : 77 bytes - Link Request : 77 bytes
- Link Proof : 77 bytes - Link Proof : 77 bytes
- Link RTT packet : 86 bytes - Link RTT packet : 83 bytes
- Link keepalive : 14 bytes - Link keepalive : 14 bytes
+1 -1
View File
@@ -57,7 +57,7 @@ What does Reticulum Offer?
* Efficient link establishment * Efficient link establishment
* Total bandwidth cost of setting up a link is only 3 packets, totalling 240 bytes * Total bandwidth cost of setting up a link is only 3 packets, totalling 237 bytes
* Low cost of keeping links open at only 0.62 bits per second * Low cost of keeping links open at only 0.62 bits per second
+1 -1
View File
@@ -1,6 +1,6 @@
var DOCUMENTATION_OPTIONS = { var DOCUMENTATION_OPTIONS = {
URL_ROOT: document.getElementById("documentation_options").getAttribute('data-url_root'), URL_ROOT: document.getElementById("documentation_options").getAttribute('data-url_root'),
VERSION: '0.2.3 beta', VERSION: '0.2.4 beta',
LANGUAGE: 'None', LANGUAGE: 'None',
COLLAPSE_INDEX: false, COLLAPSE_INDEX: false,
BUILDER: 'html', BUILDER: 'html',
+4 -4
View File
@@ -5,7 +5,7 @@
<head> <head>
<meta charset="utf-8" /> <meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Examples &#8212; Reticulum Network Stack 0.2.3 beta documentation</title> <title>Examples &#8212; Reticulum Network Stack 0.2.4 beta documentation</title>
<link rel="stylesheet" type="text/css" href="_static/pygments.css" /> <link rel="stylesheet" type="text/css" href="_static/pygments.css" />
<link rel="stylesheet" type="text/css" href="_static/classic.css" /> <link rel="stylesheet" type="text/css" href="_static/classic.css" />
@@ -27,7 +27,7 @@
<li class="right" > <li class="right" >
<a href="reference.html" title="API Reference" <a href="reference.html" title="API Reference"
accesskey="P">previous</a> |</li> accesskey="P">previous</a> |</li>
<li class="nav-item nav-item-0"><a href="index.html">Reticulum Network Stack 0.2.3 beta documentation</a> &#187;</li> <li class="nav-item nav-item-0"><a href="index.html">Reticulum Network Stack 0.2.4 beta documentation</a> &#187;</li>
<li class="nav-item nav-item-this"><a href="">Examples</a></li> <li class="nav-item nav-item-this"><a href="">Examples</a></li>
</ul> </ul>
</div> </div>
@@ -2017,7 +2017,7 @@ interface to efficiently pass files of any size over a Reticulum <a class="refer
<span class="nb">print</span><span class="p">(</span><span class="s2">&quot;&quot;</span><span class="p">)</span> <span class="nb">print</span><span class="p">(</span><span class="s2">&quot;&quot;</span><span class="p">)</span>
<span class="k">while</span> <span class="n">menu_mode</span> <span class="o">==</span> <span class="s2">&quot;downloading&quot;</span><span class="p">:</span> <span class="k">while</span> <span class="n">menu_mode</span> <span class="o">==</span> <span class="s2">&quot;downloading&quot;</span><span class="p">:</span>
<span class="k">global</span> <span class="n">current_download</span> <span class="k">global</span> <span class="n">current_download</span>
<span class="n">percent</span> <span class="o">=</span> <span class="nb">round</span><span class="p">(</span><span class="n">current_download</span><span class="o">.</span><span class="n">progress</span><span class="p">()</span> <span class="o">*</span> <span class="mf">100.0</span><span class="p">,</span> <span class="mi">1</span><span class="p">)</span> <span class="n">percent</span> <span class="o">=</span> <span class="nb">round</span><span class="p">(</span><span class="n">current_download</span><span class="o">.</span><span class="n">get_progress</span><span class="p">()</span> <span class="o">*</span> <span class="mf">100.0</span><span class="p">,</span> <span class="mi">1</span><span class="p">)</span>
<span class="nb">print</span><span class="p">((</span><span class="s2">&quot;</span><span class="se">\r</span><span class="s2">Progress: &quot;</span><span class="o">+</span><span class="nb">str</span><span class="p">(</span><span class="n">percent</span><span class="p">)</span><span class="o">+</span><span class="s2">&quot; % &quot;</span><span class="p">),</span> <span class="n">end</span><span class="o">=</span><span class="s1">&#39; &#39;</span><span class="p">)</span> <span class="nb">print</span><span class="p">((</span><span class="s2">&quot;</span><span class="se">\r</span><span class="s2">Progress: &quot;</span><span class="o">+</span><span class="nb">str</span><span class="p">(</span><span class="n">percent</span><span class="p">)</span><span class="o">+</span><span class="s2">&quot; % &quot;</span><span class="p">),</span> <span class="n">end</span><span class="o">=</span><span class="s1">&#39; &#39;</span><span class="p">)</span>
<span class="n">sys</span><span class="o">.</span><span class="n">stdout</span><span class="o">.</span><span class="n">flush</span><span class="p">()</span> <span class="n">sys</span><span class="o">.</span><span class="n">stdout</span><span class="o">.</span><span class="n">flush</span><span class="p">()</span>
<span class="n">time</span><span class="o">.</span><span class="n">sleep</span><span class="p">(</span><span class="mf">0.1</span><span class="p">)</span> <span class="n">time</span><span class="o">.</span><span class="n">sleep</span><span class="p">(</span><span class="mf">0.1</span><span class="p">)</span>
@@ -2319,7 +2319,7 @@ interface to efficiently pass files of any size over a Reticulum <a class="refer
<li class="right" > <li class="right" >
<a href="reference.html" title="API Reference" <a href="reference.html" title="API Reference"
>previous</a> |</li> >previous</a> |</li>
<li class="nav-item nav-item-0"><a href="index.html">Reticulum Network Stack 0.2.3 beta documentation</a> &#187;</li> <li class="nav-item nav-item-0"><a href="index.html">Reticulum Network Stack 0.2.4 beta documentation</a> &#187;</li>
<li class="nav-item nav-item-this"><a href="">Examples</a></li> <li class="nav-item nav-item-this"><a href="">Examples</a></li>
</ul> </ul>
</div> </div>
+36 -15
View File
@@ -5,7 +5,7 @@
<head> <head>
<meta charset="utf-8" /> <meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Index &#8212; Reticulum Network Stack 0.2.3 beta documentation</title> <title>Index &#8212; Reticulum Network Stack 0.2.4 beta documentation</title>
<link rel="stylesheet" type="text/css" href="_static/pygments.css" /> <link rel="stylesheet" type="text/css" href="_static/pygments.css" />
<link rel="stylesheet" type="text/css" href="_static/classic.css" /> <link rel="stylesheet" type="text/css" href="_static/classic.css" />
@@ -23,7 +23,7 @@
<li class="right" style="margin-right: 10px"> <li class="right" style="margin-right: 10px">
<a href="#" title="General Index" <a href="#" title="General Index"
accesskey="I">index</a></li> accesskey="I">index</a></li>
<li class="nav-item nav-item-0"><a href="index.html">Reticulum Network Stack 0.2.3 beta documentation</a> &#187;</li> <li class="nav-item nav-item-0"><a href="index.html">Reticulum Network Stack 0.2.4 beta documentation</a> &#187;</li>
<li class="nav-item nav-item-this"><a href="">Index</a></li> <li class="nav-item nav-item-this"><a href="">Index</a></li>
</ul> </ul>
</div> </div>
@@ -47,6 +47,7 @@
| <a href="#I"><strong>I</strong></a> | <a href="#I"><strong>I</strong></a>
| <a href="#K"><strong>K</strong></a> | <a href="#K"><strong>K</strong></a>
| <a href="#L"><strong>L</strong></a> | <a href="#L"><strong>L</strong></a>
| <a href="#M"><strong>M</strong></a>
| <a href="#N"><strong>N</strong></a> | <a href="#N"><strong>N</strong></a>
| <a href="#P"><strong>P</strong></a> | <a href="#P"><strong>P</strong></a>
| <a href="#R"><strong>R</strong></a> | <a href="#R"><strong>R</strong></a>
@@ -98,15 +99,13 @@
<li><a href="reference.html#RNS.Identity.decrypt">(RNS.Identity method)</a> <li><a href="reference.html#RNS.Identity.decrypt">(RNS.Identity method)</a>
</li> </li>
</ul></li> </ul></li>
<li><a href="reference.html#RNS.Transport.deregister_announce_handler">deregister_announce_handler() (RNS.Transport static method)</a>
</li>
</ul></td> </ul></td>
<td style="width: 33%; vertical-align: top;"><ul> <td style="width: 33%; vertical-align: top;"><ul>
<li><a href="reference.html#RNS.Transport.deregister_announce_handler">deregister_announce_handler() (RNS.Transport static method)</a>
</li>
<li><a href="reference.html#RNS.Destination.deregister_request_handler">deregister_request_handler() (RNS.Destination method)</a> <li><a href="reference.html#RNS.Destination.deregister_request_handler">deregister_request_handler() (RNS.Destination method)</a>
</li> </li>
<li><a href="reference.html#RNS.Destination">Destination (class in RNS)</a> <li><a href="reference.html#RNS.Destination">Destination (class in RNS)</a>
</li>
<li><a href="reference.html#RNS.Link.disable_encryption">disable_encryption() (RNS.Link method)</a>
</li> </li>
</ul></td> </ul></td>
</tr></table> </tr></table>
@@ -152,20 +151,36 @@
<ul> <ul>
<li><a href="reference.html#RNS.Identity.get_private_key">(RNS.Identity method)</a> <li><a href="reference.html#RNS.Identity.get_private_key">(RNS.Identity method)</a>
</li>
</ul></li>
<li><a href="reference.html#RNS.RequestReceipt.get_progress">get_progress() (RNS.RequestReceipt method)</a>
<ul>
<li><a href="reference.html#RNS.Resource.get_progress">(RNS.Resource method)</a>
</li> </li>
</ul></li> </ul></li>
<li><a href="reference.html#RNS.Identity.get_public_key">get_public_key() (RNS.Identity method)</a> <li><a href="reference.html#RNS.Identity.get_public_key">get_public_key() (RNS.Identity method)</a>
</li>
<li><a href="reference.html#RNS.Identity.get_random_hash">get_random_hash() (RNS.Identity static method)</a>
</li> </li>
</ul></td> </ul></td>
<td style="width: 33%; vertical-align: top;"><ul> <td style="width: 33%; vertical-align: top;"><ul>
<li><a href="reference.html#RNS.Identity.get_random_hash">get_random_hash() (RNS.Identity static method)</a>
</li>
<li><a href="reference.html#RNS.Link.get_remote_identity">get_remote_identity() (RNS.Link method)</a> <li><a href="reference.html#RNS.Link.get_remote_identity">get_remote_identity() (RNS.Link method)</a>
</li>
<li><a href="reference.html#RNS.RequestReceipt.get_request_id">get_request_id() (RNS.RequestReceipt method)</a>
</li>
<li><a href="reference.html#RNS.RequestReceipt.get_response">get_response() (RNS.RequestReceipt method)</a>
</li>
<li><a href="reference.html#RNS.RequestReceipt.get_response_time">get_response_time() (RNS.RequestReceipt method)</a>
</li> </li>
<li><a href="reference.html#RNS.PacketReceipt.get_rtt">get_rtt() (RNS.PacketReceipt method)</a> <li><a href="reference.html#RNS.PacketReceipt.get_rtt">get_rtt() (RNS.PacketReceipt method)</a>
</li> </li>
<li><a href="reference.html#RNS.PacketReceipt.get_status">get_status() (RNS.PacketReceipt method)</a> <li><a href="reference.html#RNS.PacketReceipt.get_status">get_status() (RNS.PacketReceipt method)</a>
<ul>
<li><a href="reference.html#RNS.RequestReceipt.get_status">(RNS.RequestReceipt method)</a>
</li> </li>
</ul></li>
</ul></td> </ul></td>
</tr></table> </tr></table>
@@ -229,6 +244,14 @@
</ul></td> </ul></td>
</tr></table> </tr></table>
<h2 id="M">M</h2>
<table style="width: 100%" class="indextable genindextable"><tr>
<td style="width: 33%; vertical-align: top;"><ul>
<li><a href="reference.html#RNS.Reticulum.MTU">MTU (RNS.Reticulum attribute)</a>
</li>
</ul></td>
</tr></table>
<h2 id="N">N</h2> <h2 id="N">N</h2>
<table style="width: 100%" class="indextable genindextable"><tr> <table style="width: 100%" class="indextable genindextable"><tr>
<td style="width: 33%; vertical-align: top;"><ul> <td style="width: 33%; vertical-align: top;"><ul>
@@ -253,8 +276,6 @@
<li><a href="reference.html#RNS.Transport.PATHFINDER_M">PATHFINDER_M (RNS.Transport attribute)</a> <li><a href="reference.html#RNS.Transport.PATHFINDER_M">PATHFINDER_M (RNS.Transport attribute)</a>
</li> </li>
<li><a href="reference.html#RNS.Packet.PLAIN_MDU">PLAIN_MDU (RNS.Packet attribute)</a> <li><a href="reference.html#RNS.Packet.PLAIN_MDU">PLAIN_MDU (RNS.Packet attribute)</a>
</li>
<li><a href="reference.html#RNS.Resource.progress">progress() (RNS.Resource method)</a>
</li> </li>
</ul></td> </ul></td>
</tr></table> </tr></table>
@@ -270,11 +291,13 @@
</li> </li>
<li><a href="reference.html#RNS.Destination.register_request_handler">register_request_handler() (RNS.Destination method)</a> <li><a href="reference.html#RNS.Destination.register_request_handler">register_request_handler() (RNS.Destination method)</a>
</li> </li>
</ul></td>
<td style="width: 33%; vertical-align: top;"><ul>
<li><a href="reference.html#RNS.Link.request">request() (RNS.Link method)</a> <li><a href="reference.html#RNS.Link.request">request() (RNS.Link method)</a>
</li> </li>
</ul></td>
<td style="width: 33%; vertical-align: top;"><ul>
<li><a href="reference.html#RNS.Transport.request_path">request_path() (RNS.Transport static method)</a> <li><a href="reference.html#RNS.Transport.request_path">request_path() (RNS.Transport static method)</a>
</li>
<li><a href="reference.html#RNS.RequestReceipt">RequestReceipt (class in RNS)</a>
</li> </li>
<li><a href="reference.html#RNS.Packet.resend">resend() (RNS.Packet method)</a> <li><a href="reference.html#RNS.Packet.resend">resend() (RNS.Packet method)</a>
</li> </li>
@@ -321,8 +344,6 @@
<li><a href="reference.html#RNS.PacketReceipt.set_timeout">set_timeout() (RNS.PacketReceipt method)</a> <li><a href="reference.html#RNS.PacketReceipt.set_timeout">set_timeout() (RNS.PacketReceipt method)</a>
</li> </li>
<li><a href="reference.html#RNS.PacketReceipt.set_timeout_callback">set_timeout_callback() (RNS.PacketReceipt method)</a> <li><a href="reference.html#RNS.PacketReceipt.set_timeout_callback">set_timeout_callback() (RNS.PacketReceipt method)</a>
</li>
<li><a href="reference.html#RNS.Reticulum.should_allow_unencrypted">should_allow_unencrypted() (RNS.Reticulum static method)</a>
</li> </li>
<li><a href="reference.html#RNS.Reticulum.should_use_implicit_proof">should_use_implicit_proof() (RNS.Reticulum static method)</a> <li><a href="reference.html#RNS.Reticulum.should_use_implicit_proof">should_use_implicit_proof() (RNS.Reticulum static method)</a>
</li> </li>
@@ -391,7 +412,7 @@
<li class="right" style="margin-right: 10px"> <li class="right" style="margin-right: 10px">
<a href="#" title="General Index" <a href="#" title="General Index"
>index</a></li> >index</a></li>
<li class="nav-item nav-item-0"><a href="index.html">Reticulum Network Stack 0.2.3 beta documentation</a> &#187;</li> <li class="nav-item nav-item-0"><a href="index.html">Reticulum Network Stack 0.2.4 beta documentation</a> &#187;</li>
<li class="nav-item nav-item-this"><a href="">Index</a></li> <li class="nav-item nav-item-this"><a href="">Index</a></li>
</ul> </ul>
</div> </div>
+3 -3
View File
@@ -5,7 +5,7 @@
<head> <head>
<meta charset="utf-8" /> <meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Getting Started Fast &#8212; Reticulum Network Stack 0.2.3 beta documentation</title> <title>Getting Started Fast &#8212; Reticulum Network Stack 0.2.4 beta documentation</title>
<link rel="stylesheet" type="text/css" href="_static/pygments.css" /> <link rel="stylesheet" type="text/css" href="_static/pygments.css" />
<link rel="stylesheet" type="text/css" href="_static/classic.css" /> <link rel="stylesheet" type="text/css" href="_static/classic.css" />
@@ -31,7 +31,7 @@
<li class="right" > <li class="right" >
<a href="whatis.html" title="What is Reticulum?" <a href="whatis.html" title="What is Reticulum?"
accesskey="P">previous</a> |</li> accesskey="P">previous</a> |</li>
<li class="nav-item nav-item-0"><a href="index.html">Reticulum Network Stack 0.2.3 beta documentation</a> &#187;</li> <li class="nav-item nav-item-0"><a href="index.html">Reticulum Network Stack 0.2.4 beta documentation</a> &#187;</li>
<li class="nav-item nav-item-this"><a href="">Getting Started Fast</a></li> <li class="nav-item nav-item-this"><a href="">Getting Started Fast</a></li>
</ul> </ul>
</div> </div>
@@ -166,7 +166,7 @@ dont use pip, but try this recipe:</p>
<li class="right" > <li class="right" >
<a href="whatis.html" title="What is Reticulum?" <a href="whatis.html" title="What is Reticulum?"
>previous</a> |</li> >previous</a> |</li>
<li class="nav-item nav-item-0"><a href="index.html">Reticulum Network Stack 0.2.3 beta documentation</a> &#187;</li> <li class="nav-item nav-item-0"><a href="index.html">Reticulum Network Stack 0.2.4 beta documentation</a> &#187;</li>
<li class="nav-item nav-item-this"><a href="">Getting Started Fast</a></li> <li class="nav-item nav-item-this"><a href="">Getting Started Fast</a></li>
</ul> </ul>
</div> </div>
+4 -3
View File
@@ -5,7 +5,7 @@
<head> <head>
<meta charset="utf-8" /> <meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Reticulum Network Stack Manual &#8212; Reticulum Network Stack 0.2.3 beta documentation</title> <title>Reticulum Network Stack Manual &#8212; Reticulum Network Stack 0.2.4 beta documentation</title>
<link rel="stylesheet" type="text/css" href="_static/pygments.css" /> <link rel="stylesheet" type="text/css" href="_static/pygments.css" />
<link rel="stylesheet" type="text/css" href="_static/classic.css" /> <link rel="stylesheet" type="text/css" href="_static/classic.css" />
@@ -27,7 +27,7 @@
<li class="right" > <li class="right" >
<a href="whatis.html" title="What is Reticulum?" <a href="whatis.html" title="What is Reticulum?"
accesskey="N">next</a> |</li> accesskey="N">next</a> |</li>
<li class="nav-item nav-item-0"><a href="#">Reticulum Network Stack 0.2.3 beta documentation</a> &#187;</li> <li class="nav-item nav-item-0"><a href="#">Reticulum Network Stack 0.2.4 beta documentation</a> &#187;</li>
<li class="nav-item nav-item-this"><a href="">Reticulum Network Stack Manual</a></li> <li class="nav-item nav-item-this"><a href="">Reticulum Network Stack Manual</a></li>
</ul> </ul>
</div> </div>
@@ -91,6 +91,7 @@ the development of Reticulum itself.</p>
<li class="toctree-l3"><a class="reference internal" href="reference.html#packet">Packet</a></li> <li class="toctree-l3"><a class="reference internal" href="reference.html#packet">Packet</a></li>
<li class="toctree-l3"><a class="reference internal" href="reference.html#packet-receipt">Packet Receipt</a></li> <li class="toctree-l3"><a class="reference internal" href="reference.html#packet-receipt">Packet Receipt</a></li>
<li class="toctree-l3"><a class="reference internal" href="reference.html#link">Link</a></li> <li class="toctree-l3"><a class="reference internal" href="reference.html#link">Link</a></li>
<li class="toctree-l3"><a class="reference internal" href="reference.html#request-receipt">Request Receipt</a></li>
<li class="toctree-l3"><a class="reference internal" href="reference.html#resource">Resource</a></li> <li class="toctree-l3"><a class="reference internal" href="reference.html#resource">Resource</a></li>
<li class="toctree-l3"><a class="reference internal" href="reference.html#transport">Transport</a></li> <li class="toctree-l3"><a class="reference internal" href="reference.html#transport">Transport</a></li>
</ul> </ul>
@@ -167,7 +168,7 @@ the development of Reticulum itself.</p>
<li class="right" > <li class="right" >
<a href="whatis.html" title="What is Reticulum?" <a href="whatis.html" title="What is Reticulum?"
>next</a> |</li> >next</a> |</li>
<li class="nav-item nav-item-0"><a href="#">Reticulum Network Stack 0.2.3 beta documentation</a> &#187;</li> <li class="nav-item nav-item-0"><a href="#">Reticulum Network Stack 0.2.4 beta documentation</a> &#187;</li>
<li class="nav-item nav-item-this"><a href="">Reticulum Network Stack Manual</a></li> <li class="nav-item nav-item-this"><a href="">Reticulum Network Stack Manual</a></li>
</ul> </ul>
</div> </div>
Binary file not shown.
+111 -66
View File
@@ -5,7 +5,7 @@
<head> <head>
<meta charset="utf-8" /> <meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>API Reference &#8212; Reticulum Network Stack 0.2.3 beta documentation</title> <title>API Reference &#8212; Reticulum Network Stack 0.2.4 beta documentation</title>
<link rel="stylesheet" type="text/css" href="_static/pygments.css" /> <link rel="stylesheet" type="text/css" href="_static/pygments.css" />
<link rel="stylesheet" type="text/css" href="_static/classic.css" /> <link rel="stylesheet" type="text/css" href="_static/classic.css" />
@@ -31,7 +31,7 @@
<li class="right" > <li class="right" >
<a href="understanding.html" title="Understanding Reticulum" <a href="understanding.html" title="Understanding Reticulum"
accesskey="P">previous</a> |</li> accesskey="P">previous</a> |</li>
<li class="nav-item nav-item-0"><a href="index.html">Reticulum Network Stack 0.2.3 beta documentation</a> &#187;</li> <li class="nav-item nav-item-0"><a href="index.html">Reticulum Network Stack 0.2.4 beta documentation</a> &#187;</li>
<li class="nav-item nav-item-this"><a href="">API Reference</a></li> <li class="nav-item nav-item-this"><a href="">API Reference</a></li>
</ul> </ul>
</div> </div>
@@ -72,16 +72,16 @@ terminated (unless killed forcibly).</p>
programs that use RNS starting and terminating at different times, programs that use RNS starting and terminating at different times,
it will be advantageous to run a master RNS instance as a daemon for it will be advantageous to run a master RNS instance as a daemon for
other programs to use on demand.</p> other programs to use on demand.</p>
<dl class="py method"> <dl class="py attribute">
<dt class="sig sig-object py" id="RNS.Reticulum.should_allow_unencrypted"> <dt class="sig sig-object py" id="RNS.Reticulum.MTU">
<em class="property"><span class="pre">static</span> </em><span class="sig-name descname"><span class="pre">should_allow_unencrypted</span></span><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#RNS.Reticulum.should_allow_unencrypted" title="Permalink to this definition"></a></dt> <span class="sig-name descname"><span class="pre">MTU</span></span><em class="property"> <span class="pre">=</span> <span class="pre">500</span></em><a class="headerlink" href="#RNS.Reticulum.MTU" title="Permalink to this definition"></a></dt>
<dd><p>Returns whether unencrypted links are allowed by the <dd><p>The MTU that Reticulum adheres to, and will expect other peers to
current configuration.</p> adhere to. By default, the MTU is 500 bytes. In custom RNS network
<dl class="field-list simple"> implementations, it is possible to change this value, but doing so will
<dt class="field-odd">Returns</dt> completely break compatibility with all other RNS networks. An identical
<dd class="field-odd"><p>True if the current running configuration allows downgrading links to plaintext. False if not.</p> MTU is a prerequisite for peers to communicate in the same network.</p>
</dd> <p>Unless you really know what you are doing, the MTU should be left at
</dl> the default value.</p>
</dd></dl> </dd></dl>
<dl class="py method"> <dl class="py method">
@@ -215,6 +215,21 @@ for addressable hashes and other purposes. Non-configurable.</p>
</dl> </dl>
</dd></dl> </dd></dl>
<dl class="py method">
<dt class="sig sig-object py" id="RNS.Identity.from_bytes">
<em class="property"><span class="pre">static</span> </em><span class="sig-name descname"><span class="pre">from_bytes</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">prv_bytes</span></span></em><span class="sig-paren">)</span><a class="headerlink" href="#RNS.Identity.from_bytes" title="Permalink to this definition"></a></dt>
<dd><p>Create a new <a class="reference internal" href="#api-identity"><span class="std std-ref">RNS.Identity</span></a> instance from <em>bytes</em> of private key.
Can be used to load previously created and saved identities into Reticulum.</p>
<dl class="field-list simple">
<dt class="field-odd">Parameters</dt>
<dd class="field-odd"><p><strong>prv_bytes</strong> The <em>bytes</em> of private a saved private key. <strong>HAZARD!</strong> Never use this to generate a new key by feeding random data in prv_bytes.</p>
</dd>
<dt class="field-even">Returns</dt>
<dd class="field-even"><p>A <a class="reference internal" href="#api-identity"><span class="std std-ref">RNS.Identity</span></a> instance, or <em>None</em> if the <em>bytes</em> data was invalid.</p>
</dd>
</dl>
</dd></dl>
<dl class="py method"> <dl class="py method">
<dt class="sig sig-object py" id="RNS.Identity.from_file"> <dt class="sig sig-object py" id="RNS.Identity.from_file">
<em class="property"><span class="pre">static</span> </em><span class="sig-name descname"><span class="pre">from_file</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">path</span></span></em><span class="sig-paren">)</span><a class="headerlink" href="#RNS.Identity.from_file" title="Permalink to this definition"></a></dt> <em class="property"><span class="pre">static</span> </em><span class="sig-name descname"><span class="pre">from_file</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">path</span></span></em><span class="sig-paren">)</span><a class="headerlink" href="#RNS.Identity.from_file" title="Permalink to this definition"></a></dt>
@@ -246,21 +261,6 @@ communication for the identity. Be very careful with this method.</p>
</dl> </dl>
</dd></dl> </dd></dl>
<dl class="py method">
<dt class="sig sig-object py" id="RNS.Identity.from_bytes">
<em class="property"><span class="pre">static</span> </em><span class="sig-name descname"><span class="pre">from_bytes</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">prv_bytes</span></span></em><span class="sig-paren">)</span><a class="headerlink" href="#RNS.Identity.from_bytes" title="Permalink to this definition"></a></dt>
<dd><p>Create a new <a class="reference internal" href="#api-identity"><span class="std std-ref">RNS.Identity</span></a> instance from <em>bytes</em> of private key.
Can be used to load previously created and saved identities into Reticulum.</p>
<dl class="field-list simple">
<dt class="field-odd">Parameters</dt>
<dd class="field-odd"><p><strong>prv_bytes</strong> The <em>bytes</em> of private a saved private key. <strong>HAZARD!</strong> Never not use this to generate a new key by feeding random data in prv_bytes.</p>
</dd>
<dt class="field-even">Returns</dt>
<dd class="field-even"><p>A <a class="reference internal" href="#api-identity"><span class="std std-ref">RNS.Identity</span></a> instance, or <em>None</em> if the <em>bytes</em> data was invalid.</p>
</dd>
</dl>
</dd></dl>
<dl class="py method"> <dl class="py method">
<dt class="sig sig-object py" id="RNS.Identity.get_private_key"> <dt class="sig sig-object py" id="RNS.Identity.get_private_key">
<span class="sig-name descname"><span class="pre">get_private_key</span></span><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#RNS.Identity.get_private_key" title="Permalink to this definition"></a></dt> <span class="sig-name descname"><span class="pre">get_private_key</span></span><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#RNS.Identity.get_private_key" title="Permalink to this definition"></a></dt>
@@ -645,7 +645,7 @@ unless other app_data is specified in the <em>announce</em> method.</p>
<span id="api-packet"></span><h3>Packet<a class="headerlink" href="#packet" title="Permalink to this headline"></a></h3> <span id="api-packet"></span><h3>Packet<a class="headerlink" href="#packet" title="Permalink to this headline"></a></h3>
<dl class="py class"> <dl class="py class">
<dt class="sig sig-object py" id="RNS.Packet"> <dt class="sig sig-object py" id="RNS.Packet">
<em class="property"><span class="pre">class</span> </em><span class="sig-prename descclassname"><span class="pre">RNS.</span></span><span class="sig-name descname"><span class="pre">Packet</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">destination</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">data</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">packet_type</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">0</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">context</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">0</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">transport_type</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">0</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">header_type</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">0</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">transport_id</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">attached_interface</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">create_receipt</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">True</span></span></em><span class="sig-paren">)</span><a class="headerlink" href="#RNS.Packet" title="Permalink to this definition"></a></dt> <em class="property"><span class="pre">class</span> </em><span class="sig-prename descclassname"><span class="pre">RNS.</span></span><span class="sig-name descname"><span class="pre">Packet</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">destination</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">data</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">create_receipt</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">True</span></span></em><span class="sig-paren">)</span><a class="headerlink" href="#RNS.Packet" title="Permalink to this definition"></a></dt>
<dd><p>The Packet class is used to create packet instances that can be sent <dd><p>The Packet class is used to create packet instances that can be sent
over a Reticulum network. Packets to will automatically be encrypted if over a Reticulum network. Packets to will automatically be encrypted if
they are adressed to a <code class="docutils literal notranslate"><span class="pre">RNS.Destination.SINGLE</span></code> destination, they are adressed to a <code class="docutils literal notranslate"><span class="pre">RNS.Destination.SINGLE</span></code> destination,
@@ -660,11 +660,6 @@ destinations, reticulum will use ephemeral keys, and offers <strong>Forward Secr
<li><p><strong>destination</strong> A <a class="reference internal" href="#api-destination"><span class="std std-ref">RNS.Destination</span></a> instance to which the packet will be sent.</p></li> <li><p><strong>destination</strong> A <a class="reference internal" href="#api-destination"><span class="std std-ref">RNS.Destination</span></a> instance to which the packet will be sent.</p></li>
<li><p><strong>data</strong> The data payload to be included in the packet as <em>bytes</em>.</p></li> <li><p><strong>data</strong> The data payload to be included in the packet as <em>bytes</em>.</p></li>
<li><p><strong>create_receipt</strong> Specifies whether a <a class="reference internal" href="#api-packetreceipt"><span class="std std-ref">RNS.PacketReceipt</span></a> should be created when instantiating the packet.</p></li> <li><p><strong>create_receipt</strong> Specifies whether a <a class="reference internal" href="#api-packetreceipt"><span class="std std-ref">RNS.PacketReceipt</span></a> should be created when instantiating the packet.</p></li>
<li><p><strong>type</strong> Internal use by <a class="reference internal" href="#api-transport"><span class="std std-ref">RNS.Transport</span></a>. Defaults to <code class="docutils literal notranslate"><span class="pre">RNS.Packet.DATA</span></code>, and should not be specified.</p></li>
<li><p><strong>context</strong> Internal use by <a class="reference internal" href="#api-transport"><span class="std std-ref">RNS.Transport</span></a>. Ignore.</p></li>
<li><p><strong>transport_type</strong> Internal use by <a class="reference internal" href="#api-transport"><span class="std std-ref">RNS.Transport</span></a>. Ignore.</p></li>
<li><p><strong>transport_id</strong> Internal use by <a class="reference internal" href="#api-transport"><span class="std std-ref">RNS.Transport</span></a>. Ignore.</p></li>
<li><p><strong>attached_interface</strong> Internal use by <a class="reference internal" href="#api-transport"><span class="std std-ref">RNS.Transport</span></a>. Ignore.</p></li>
</ul> </ul>
</dd> </dd>
</dl> </dl>
@@ -709,11 +704,11 @@ destinations, reticulum will use ephemeral keys, and offers <strong>Forward Secr
<span id="api-packetreceipt"></span><h3>Packet Receipt<a class="headerlink" href="#packet-receipt" title="Permalink to this headline"></a></h3> <span id="api-packetreceipt"></span><h3>Packet Receipt<a class="headerlink" href="#packet-receipt" title="Permalink to this headline"></a></h3>
<dl class="py class"> <dl class="py class">
<dt class="sig sig-object py" id="RNS.PacketReceipt"> <dt class="sig sig-object py" id="RNS.PacketReceipt">
<em class="property"><span class="pre">class</span> </em><span class="sig-prename descclassname"><span class="pre">RNS.</span></span><span class="sig-name descname"><span class="pre">PacketReceipt</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">packet</span></span></em><span class="sig-paren">)</span><a class="headerlink" href="#RNS.PacketReceipt" title="Permalink to this definition"></a></dt> <em class="property"><span class="pre">class</span> </em><span class="sig-prename descclassname"><span class="pre">RNS.</span></span><span class="sig-name descname"><span class="pre">PacketReceipt</span></span><a class="headerlink" href="#RNS.PacketReceipt" title="Permalink to this definition"></a></dt>
<dd><p>The PacketReceipt class is used to receive notifications about <dd><p>The PacketReceipt class is used to receive notifications about
<a class="reference internal" href="#api-packet"><span class="std std-ref">RNS.Packet</span></a> instances sent over the network. Instances <a class="reference internal" href="#api-packet"><span class="std std-ref">RNS.Packet</span></a> instances sent over the network. Instances
of this class should never be created manually, but always returned of this class are never created manually, but always returned from
from a the <em>send()</em> method of a <a class="reference internal" href="#api-packet"><span class="std std-ref">RNS.Packet</span></a> instance.</p> the <em>send()</em> method of a <a class="reference internal" href="#api-packet"><span class="std std-ref">RNS.Packet</span></a> instance.</p>
<dl class="py method"> <dl class="py method">
<dt class="sig sig-object py" id="RNS.PacketReceipt.get_status"> <dt class="sig sig-object py" id="RNS.PacketReceipt.get_status">
<span class="sig-name descname"><span class="pre">get_status</span></span><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#RNS.PacketReceipt.get_status" title="Permalink to this definition"></a></dt> <span class="sig-name descname"><span class="pre">get_status</span></span><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#RNS.PacketReceipt.get_status" title="Permalink to this definition"></a></dt>
@@ -774,17 +769,16 @@ from a the <em>send()</em> method of a <a class="reference internal" href="#api-
<span id="api-link"></span><h3>Link<a class="headerlink" href="#link" title="Permalink to this headline"></a></h3> <span id="api-link"></span><h3>Link<a class="headerlink" href="#link" title="Permalink to this headline"></a></h3>
<dl class="py class"> <dl class="py class">
<dt class="sig sig-object py" id="RNS.Link"> <dt class="sig sig-object py" id="RNS.Link">
<em class="property"><span class="pre">class</span> </em><span class="sig-prename descclassname"><span class="pre">RNS.</span></span><span class="sig-name descname"><span class="pre">Link</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">destination</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">established_callback</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">closed_callback</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">owner</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">peer_pub_bytes</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">peer_sig_pub_bytes</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span></em><span class="sig-paren">)</span><a class="headerlink" href="#RNS.Link" title="Permalink to this definition"></a></dt> <em class="property"><span class="pre">class</span> </em><span class="sig-prename descclassname"><span class="pre">RNS.</span></span><span class="sig-name descname"><span class="pre">Link</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">destination</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">established_callback</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">closed_callback</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span></em><span class="sig-paren">)</span><a class="headerlink" href="#RNS.Link" title="Permalink to this definition"></a></dt>
<dd><p>This class.</p> <dd><p>This class is used to establish and manage links to other peers. When a
link instance is created, Reticulum will attempt to establish verified
connectivity with the specified destination.</p>
<dl class="field-list simple"> <dl class="field-list simple">
<dt class="field-odd">Parameters</dt> <dt class="field-odd">Parameters</dt>
<dd class="field-odd"><ul class="simple"> <dd class="field-odd"><ul class="simple">
<li><p><strong>destination</strong> A <a class="reference internal" href="#api-destination"><span class="std std-ref">RNS.Destination</span></a> instance which to establish a link to.</p></li> <li><p><strong>destination</strong> A <a class="reference internal" href="#api-destination"><span class="std std-ref">RNS.Destination</span></a> instance which to establish a link to.</p></li>
<li><p><strong>established_callback</strong> A function or method with the signature <em>callback(link)</em> to be called when the link has been established.</p></li> <li><p><strong>established_callback</strong> An optional function or method with the signature <em>callback(link)</em> to be called when the link has been established.</p></li>
<li><p><strong>closed_callback</strong> A function or method with the signature <em>callback(link)</em> to be called when the link is closed.</p></li> <li><p><strong>closed_callback</strong> An optional function or method with the signature <em>callback(link)</em> to be called when the link is closed.</p></li>
<li><p><strong>owner</strong> Internal use by <a class="reference internal" href="#api-transport"><span class="std std-ref">RNS.Transport</span></a>, ignore this argument.</p></li>
<li><p><strong>peer_pub_bytes</strong> Internal use, ignore this argument.</p></li>
<li><p><strong>peer_sig_pub_bytes</strong> Internal use, ignore this argument.</p></li>
</ul> </ul>
</dd> </dd>
</dl> </dl>
@@ -796,7 +790,7 @@ from a the <em>send()</em> method of a <a class="reference internal" href="#api-
<dl class="py attribute"> <dl class="py attribute">
<dt class="sig sig-object py" id="RNS.Link.ESTABLISHMENT_TIMEOUT_PER_HOP"> <dt class="sig sig-object py" id="RNS.Link.ESTABLISHMENT_TIMEOUT_PER_HOP">
<span class="sig-name descname"><span class="pre">ESTABLISHMENT_TIMEOUT_PER_HOP</span></span><em class="property"> <span class="pre">=</span> <span class="pre">3</span></em><a class="headerlink" href="#RNS.Link.ESTABLISHMENT_TIMEOUT_PER_HOP" title="Permalink to this definition"></a></dt> <span class="sig-name descname"><span class="pre">ESTABLISHMENT_TIMEOUT_PER_HOP</span></span><em class="property"> <span class="pre">=</span> <span class="pre">5</span></em><a class="headerlink" href="#RNS.Link.ESTABLISHMENT_TIMEOUT_PER_HOP" title="Permalink to this definition"></a></dt>
<dd><p>Default timeout for link establishment in seconds per hop to destination.</p> <dd><p>Default timeout for link establishment in seconds per hop to destination.</p>
</dd></dl> </dd></dl>
@@ -834,6 +828,9 @@ thus preserved. This method can be used for authentication.</p>
<li><p><strong>timeout</strong> An optional timeout in seconds for the request. If <em>None</em> is supplied it will be calculated based on link RTT.</p></li> <li><p><strong>timeout</strong> An optional timeout in seconds for the request. If <em>None</em> is supplied it will be calculated based on link RTT.</p></li>
</ul> </ul>
</dd> </dd>
<dt class="field-even">Returns</dt>
<dd class="field-even"><p>A <a class="reference internal" href="#api-requestreceipt"><span class="std std-ref">RNS.RequestReceipt</span></a> instance if the request was sent, or <em>False</em> if it was not.</p>
</dd>
</dl> </dl>
</dd></dl> </dd></dl>
@@ -960,16 +957,65 @@ identified over this link.</p>
</dl> </dl>
</dd></dl> </dd></dl>
</dd></dl>
</div>
<div class="section" id="request-receipt">
<span id="api-requestreceipt"></span><h3>Request Receipt<a class="headerlink" href="#request-receipt" title="Permalink to this headline"></a></h3>
<dl class="py class">
<dt class="sig sig-object py" id="RNS.RequestReceipt">
<em class="property"><span class="pre">class</span> </em><span class="sig-prename descclassname"><span class="pre">RNS.</span></span><span class="sig-name descname"><span class="pre">RequestReceipt</span></span><a class="headerlink" href="#RNS.RequestReceipt" title="Permalink to this definition"></a></dt>
<dd><p>An instance of this class is returned by the <code class="docutils literal notranslate"><span class="pre">request</span></code> method of <code class="docutils literal notranslate"><span class="pre">RNS.Link</span></code>
instances. It should never be instantiated manually. It provides methods to
check status, response time and response data when the request concludes.</p>
<dl class="py method"> <dl class="py method">
<dt class="sig sig-object py" id="RNS.Link.disable_encryption"> <dt class="sig sig-object py" id="RNS.RequestReceipt.get_request_id">
<span class="sig-name descname"><span class="pre">disable_encryption</span></span><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#RNS.Link.disable_encryption" title="Permalink to this definition"></a></dt> <span class="sig-name descname"><span class="pre">get_request_id</span></span><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#RNS.RequestReceipt.get_request_id" title="Permalink to this definition"></a></dt>
<dd><p>HAZARDOUS. This will downgrade the link to encryptionless. All <dd><dl class="field-list simple">
information over the link will be sent in plaintext. Never use <dt class="field-odd">Returns</dt>
this in production applications. Should only be used for debugging <dd class="field-odd"><p>The request ID as <em>bytes</em>.</p>
purposes, and will disappear in a future version.</p> </dd>
<p>If encryptionless links are not explicitly allowed in the users </dl>
configuration file, Reticulum will terminate itself along with the </dd></dl>
client application and throw an error message to the user.</p>
<dl class="py method">
<dt class="sig sig-object py" id="RNS.RequestReceipt.get_status">
<span class="sig-name descname"><span class="pre">get_status</span></span><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#RNS.RequestReceipt.get_status" title="Permalink to this definition"></a></dt>
<dd><dl class="field-list simple">
<dt class="field-odd">Returns</dt>
<dd class="field-odd"><p>The current status of the request, one of <code class="docutils literal notranslate"><span class="pre">RNS.RequestReceipt.FAILED</span></code>, <code class="docutils literal notranslate"><span class="pre">RNS.RequestReceipt.SENT</span></code>, <code class="docutils literal notranslate"><span class="pre">RNS.RequestReceipt.DELIVERED</span></code>, <code class="docutils literal notranslate"><span class="pre">RNS.RequestReceipt.READY</span></code>.</p>
</dd>
</dl>
</dd></dl>
<dl class="py method">
<dt class="sig sig-object py" id="RNS.RequestReceipt.get_progress">
<span class="sig-name descname"><span class="pre">get_progress</span></span><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#RNS.RequestReceipt.get_progress" title="Permalink to this definition"></a></dt>
<dd><dl class="field-list simple">
<dt class="field-odd">Returns</dt>
<dd class="field-odd"><p>The progress of a response being received as a <em>float</em> between 0.0 and 1.0.</p>
</dd>
</dl>
</dd></dl>
<dl class="py method">
<dt class="sig sig-object py" id="RNS.RequestReceipt.get_response">
<span class="sig-name descname"><span class="pre">get_response</span></span><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#RNS.RequestReceipt.get_response" title="Permalink to this definition"></a></dt>
<dd><dl class="field-list simple">
<dt class="field-odd">Returns</dt>
<dd class="field-odd"><p>The response as <em>bytes</em> if it is ready, otherwise <em>None</em>.</p>
</dd>
</dl>
</dd></dl>
<dl class="py method">
<dt class="sig sig-object py" id="RNS.RequestReceipt.get_response_time">
<span class="sig-name descname"><span class="pre">get_response_time</span></span><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#RNS.RequestReceipt.get_response_time" title="Permalink to this definition"></a></dt>
<dd><dl class="field-list simple">
<dt class="field-odd">Returns</dt>
<dd class="field-odd"><p>The response time of the request in seconds.</p>
</dd>
</dl>
</dd></dl> </dd></dl>
</dd></dl> </dd></dl>
@@ -979,7 +1025,7 @@ client application and throw an error message to the user.</p>
<span id="api-resource"></span><h3>Resource<a class="headerlink" href="#resource" title="Permalink to this headline"></a></h3> <span id="api-resource"></span><h3>Resource<a class="headerlink" href="#resource" title="Permalink to this headline"></a></h3>
<dl class="py class"> <dl class="py class">
<dt class="sig sig-object py" id="RNS.Resource"> <dt class="sig sig-object py" id="RNS.Resource">
<em class="property"><span class="pre">class</span> </em><span class="sig-prename descclassname"><span class="pre">RNS.</span></span><span class="sig-name descname"><span class="pre">Resource</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">data</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">link</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">advertise</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">True</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">auto_compress</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">True</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">callback</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">progress_callback</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">timeout</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">segment_index</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">1</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">original_hash</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">request_id</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">is_response</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">False</span></span></em><span class="sig-paren">)</span><a class="headerlink" href="#RNS.Resource" title="Permalink to this definition"></a></dt> <em class="property"><span class="pre">class</span> </em><span class="sig-prename descclassname"><span class="pre">RNS.</span></span><span class="sig-name descname"><span class="pre">Resource</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">data</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">link</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">advertise</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">True</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">auto_compress</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">True</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">callback</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">progress_callback</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">timeout</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span></em><span class="sig-paren">)</span><a class="headerlink" href="#RNS.Resource" title="Permalink to this definition"></a></dt>
<dd><p>The Resource class allows transferring arbitrary amounts <dd><p>The Resource class allows transferring arbitrary amounts
of data over a link. It will automatically handle sequencing, of data over a link. It will automatically handle sequencing,
compression, coordination and checksumming.</p> compression, coordination and checksumming.</p>
@@ -988,14 +1034,10 @@ compression, coordination and checksumming.</p>
<dd class="field-odd"><ul class="simple"> <dd class="field-odd"><ul class="simple">
<li><p><strong>data</strong> The data to be transferred. Can be <em>bytes</em> or an open <em>file handle</em>. See the <a class="reference internal" href="examples.html#example-filetransfer"><span class="std std-ref">Filetransfer Example</span></a> for details.</p></li> <li><p><strong>data</strong> The data to be transferred. Can be <em>bytes</em> or an open <em>file handle</em>. See the <a class="reference internal" href="examples.html#example-filetransfer"><span class="std std-ref">Filetransfer Example</span></a> for details.</p></li>
<li><p><strong>link</strong> The <a class="reference internal" href="#api-link"><span class="std std-ref">RNS.Link</span></a> instance on which to transfer the data.</p></li> <li><p><strong>link</strong> The <a class="reference internal" href="#api-link"><span class="std std-ref">RNS.Link</span></a> instance on which to transfer the data.</p></li>
<li><p><strong>advertise</strong> Whether to automatically advertise the resource. Can be <em>True</em> or <em>False</em>.</p></li> <li><p><strong>advertise</strong> Optional. Whether to automatically advertise the resource. Can be <em>True</em> or <em>False</em>.</p></li>
<li><p><strong>auto_compress</strong> Whether to auto-compress the resource. Can be <em>True</em> or <em>False</em>.</p></li> <li><p><strong>auto_compress</strong> Optional. Whether to auto-compress the resource. Can be <em>True</em> or <em>False</em>.</p></li>
<li><p><strong>callback</strong> A <em>callable</em> with the signature <em>callback(resource)</em>. Will be called when the resource transfer concludes.</p></li> <li><p><strong>callback</strong> An optional <em>callable</em> with the signature <em>callback(resource)</em>. Will be called when the resource transfer concludes.</p></li>
<li><p><strong>progress_callback</strong> A <em>callable</em> with the signature <em>callback(resource)</em>. Will be called whenever the resource transfer progress is updated.</p></li> <li><p><strong>progress_callback</strong> An optional <em>callable</em> with the signature <em>callback(resource)</em>. Will be called whenever the resource transfer progress is updated.</p></li>
<li><p><strong>segment_index</strong> Internal use, ignore.</p></li>
<li><p><strong>original_hash</strong> Internal use, ignore.</p></li>
<li><p><strong>is_request</strong> Internal use, ignore.</p></li>
<li><p><strong>is_response</strong> Internal use, ignore.</p></li>
</ul> </ul>
</dd> </dd>
</dl> </dl>
@@ -1013,8 +1055,8 @@ the resource advertisement it will begin transferring.</p>
</dd></dl> </dd></dl>
<dl class="py method"> <dl class="py method">
<dt class="sig sig-object py" id="RNS.Resource.progress"> <dt class="sig sig-object py" id="RNS.Resource.get_progress">
<span class="sig-name descname"><span class="pre">progress</span></span><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#RNS.Resource.progress" title="Permalink to this definition"></a></dt> <span class="sig-name descname"><span class="pre">get_progress</span></span><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#RNS.Resource.get_progress" title="Permalink to this definition"></a></dt>
<dd><dl class="field-list simple"> <dd><dl class="field-list simple">
<dt class="field-odd">Returns</dt> <dt class="field-odd">Returns</dt>
<dd class="field-odd"><p>The current progress of the resource transfer as a <em>float</em> between 0.0 and 1.0.</p> <dd class="field-odd"><p>The current progress of the resource transfer as a <em>float</em> between 0.0 and 1.0.</p>
@@ -1030,7 +1072,9 @@ the resource advertisement it will begin transferring.</p>
<dl class="py class"> <dl class="py class">
<dt class="sig sig-object py" id="RNS.Transport"> <dt class="sig sig-object py" id="RNS.Transport">
<em class="property"><span class="pre">class</span> </em><span class="sig-prename descclassname"><span class="pre">RNS.</span></span><span class="sig-name descname"><span class="pre">Transport</span></span><a class="headerlink" href="#RNS.Transport" title="Permalink to this definition"></a></dt> <em class="property"><span class="pre">class</span> </em><span class="sig-prename descclassname"><span class="pre">RNS.</span></span><span class="sig-name descname"><span class="pre">Transport</span></span><a class="headerlink" href="#RNS.Transport" title="Permalink to this definition"></a></dt>
<dd><dl class="py attribute"> <dd><p>Through static methods of this class you can interact with Reticulums
Transport system.</p>
<dl class="py attribute">
<dt class="sig sig-object py" id="RNS.Transport.PATHFINDER_M"> <dt class="sig sig-object py" id="RNS.Transport.PATHFINDER_M">
<span class="sig-name descname"><span class="pre">PATHFINDER_M</span></span><em class="property"> <span class="pre">=</span> <span class="pre">128</span></em><a class="headerlink" href="#RNS.Transport.PATHFINDER_M" title="Permalink to this definition"></a></dt> <span class="sig-name descname"><span class="pre">PATHFINDER_M</span></span><em class="property"> <span class="pre">=</span> <span class="pre">128</span></em><a class="headerlink" href="#RNS.Transport.PATHFINDER_M" title="Permalink to this definition"></a></dt>
<dd><p>Maximum amount of hops that Reticulum will transport a packet.</p> <dd><p>Maximum amount of hops that Reticulum will transport a packet.</p>
@@ -1120,6 +1164,7 @@ will announce it.</p>
<li><a class="reference internal" href="#packet">Packet</a></li> <li><a class="reference internal" href="#packet">Packet</a></li>
<li><a class="reference internal" href="#packet-receipt">Packet Receipt</a></li> <li><a class="reference internal" href="#packet-receipt">Packet Receipt</a></li>
<li><a class="reference internal" href="#link">Link</a></li> <li><a class="reference internal" href="#link">Link</a></li>
<li><a class="reference internal" href="#request-receipt">Request Receipt</a></li>
<li><a class="reference internal" href="#resource">Resource</a></li> <li><a class="reference internal" href="#resource">Resource</a></li>
<li><a class="reference internal" href="#transport">Transport</a></li> <li><a class="reference internal" href="#transport">Transport</a></li>
</ul> </ul>
@@ -1167,7 +1212,7 @@ will announce it.</p>
<li class="right" > <li class="right" >
<a href="understanding.html" title="Understanding Reticulum" <a href="understanding.html" title="Understanding Reticulum"
>previous</a> |</li> >previous</a> |</li>
<li class="nav-item nav-item-0"><a href="index.html">Reticulum Network Stack 0.2.3 beta documentation</a> &#187;</li> <li class="nav-item nav-item-0"><a href="index.html">Reticulum Network Stack 0.2.4 beta documentation</a> &#187;</li>
<li class="nav-item nav-item-this"><a href="">API Reference</a></li> <li class="nav-item nav-item-this"><a href="">API Reference</a></li>
</ul> </ul>
</div> </div>
+3 -3
View File
@@ -5,7 +5,7 @@
<head> <head>
<meta charset="utf-8" /> <meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Search &#8212; Reticulum Network Stack 0.2.3 beta documentation</title> <title>Search &#8212; Reticulum Network Stack 0.2.4 beta documentation</title>
<link rel="stylesheet" type="text/css" href="_static/pygments.css" /> <link rel="stylesheet" type="text/css" href="_static/pygments.css" />
<link rel="stylesheet" type="text/css" href="_static/classic.css" /> <link rel="stylesheet" type="text/css" href="_static/classic.css" />
@@ -29,7 +29,7 @@
<li class="right" style="margin-right: 10px"> <li class="right" style="margin-right: 10px">
<a href="genindex.html" title="General Index" <a href="genindex.html" title="General Index"
accesskey="I">index</a></li> accesskey="I">index</a></li>
<li class="nav-item nav-item-0"><a href="index.html">Reticulum Network Stack 0.2.3 beta documentation</a> &#187;</li> <li class="nav-item nav-item-0"><a href="index.html">Reticulum Network Stack 0.2.4 beta documentation</a> &#187;</li>
<li class="nav-item nav-item-this"><a href="">Search</a></li> <li class="nav-item nav-item-this"><a href="">Search</a></li>
</ul> </ul>
</div> </div>
@@ -85,7 +85,7 @@
<li class="right" style="margin-right: 10px"> <li class="right" style="margin-right: 10px">
<a href="genindex.html" title="General Index" <a href="genindex.html" title="General Index"
>index</a></li> >index</a></li>
<li class="nav-item nav-item-0"><a href="index.html">Reticulum Network Stack 0.2.3 beta documentation</a> &#187;</li> <li class="nav-item nav-item-0"><a href="index.html">Reticulum Network Stack 0.2.4 beta documentation</a> &#187;</li>
<li class="nav-item nav-item-this"><a href="">Search</a></li> <li class="nav-item nav-item-this"><a href="">Search</a></li>
</ul> </ul>
</div> </div>
File diff suppressed because one or more lines are too long
+5 -5
View File
@@ -5,7 +5,7 @@
<head> <head>
<meta charset="utf-8" /> <meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Understanding Reticulum &#8212; Reticulum Network Stack 0.2.3 beta documentation</title> <title>Understanding Reticulum &#8212; Reticulum Network Stack 0.2.4 beta documentation</title>
<link rel="stylesheet" type="text/css" href="_static/pygments.css" /> <link rel="stylesheet" type="text/css" href="_static/pygments.css" />
<link rel="stylesheet" type="text/css" href="_static/classic.css" /> <link rel="stylesheet" type="text/css" href="_static/classic.css" />
@@ -31,7 +31,7 @@
<li class="right" > <li class="right" >
<a href="gettingstartedfast.html" title="Getting Started Fast" <a href="gettingstartedfast.html" title="Getting Started Fast"
accesskey="P">previous</a> |</li> accesskey="P">previous</a> |</li>
<li class="nav-item nav-item-0"><a href="index.html">Reticulum Network Stack 0.2.3 beta documentation</a> &#187;</li> <li class="nav-item nav-item-0"><a href="index.html">Reticulum Network Stack 0.2.4 beta documentation</a> &#187;</li>
<li class="nav-item nav-item-this"><a href="">Understanding Reticulum</a></li> <li class="nav-item nav-item-this"><a href="">Understanding Reticulum</a></li>
</ul> </ul>
</div> </div>
@@ -490,7 +490,7 @@ At the same time we establish an efficient encrypted channel. The setup of this
terms of bandwidth, so it can be used just for a short exchange, and then recreated as needed, which will terms of bandwidth, so it can be used just for a short exchange, and then recreated as needed, which will
also rotate encryption keys. The link can also be kept alive for longer periods of time, if this is also rotate encryption keys. The link can also be kept alive for longer periods of time, if this is
more suitable to the application. The procedure also inserts the <em>link id</em> , a hash calculated from the link request packet, into the memory of forwarding nodes, which means that the communicating nodes can thereafter reach each other simply by referring to this <em>link id</em>.</p> more suitable to the application. The procedure also inserts the <em>link id</em> , a hash calculated from the link request packet, into the memory of forwarding nodes, which means that the communicating nodes can thereafter reach each other simply by referring to this <em>link id</em>.</p>
<p>The combined bandwidth cost of setting up a link is 3 packets totalling 240 bytes (more info in the <p>The combined bandwidth cost of setting up a link is 3 packets totalling 237 bytes (more info in the
<a class="reference internal" href="#understanding-packetformat"><span class="std std-ref">Binary Packet Format</span></a> section). The amount of bandwidth used on keeping <a class="reference internal" href="#understanding-packetformat"><span class="std std-ref">Binary Packet Format</span></a> section). The amount of bandwidth used on keeping
a link open is practically negligible, at 0.62 bits per second. Even on a slow 1200 bits per second packet a link open is practically negligible, at 0.62 bits per second. Even on a slow 1200 bits per second packet
radio channel, 100 concurrent links will still leave 95% channel capacity for actual data.</p> radio channel, 100 concurrent links will still leave 95% channel capacity for actual data.</p>
@@ -764,7 +764,7 @@ proof 11
- Announce : 151 bytes - Announce : 151 bytes
- Link Request : 77 bytes - Link Request : 77 bytes
- Link Proof : 77 bytes - Link Proof : 77 bytes
- Link RTT packet : 86 bytes - Link RTT packet : 83 bytes
- Link keepalive : 14 bytes - Link keepalive : 14 bytes
</pre></div> </pre></div>
</div> </div>
@@ -853,7 +853,7 @@ proof 11
<li class="right" > <li class="right" >
<a href="gettingstartedfast.html" title="Getting Started Fast" <a href="gettingstartedfast.html" title="Getting Started Fast"
>previous</a> |</li> >previous</a> |</li>
<li class="nav-item nav-item-0"><a href="index.html">Reticulum Network Stack 0.2.3 beta documentation</a> &#187;</li> <li class="nav-item nav-item-0"><a href="index.html">Reticulum Network Stack 0.2.4 beta documentation</a> &#187;</li>
<li class="nav-item nav-item-this"><a href="">Understanding Reticulum</a></li> <li class="nav-item nav-item-this"><a href="">Understanding Reticulum</a></li>
</ul> </ul>
</div> </div>
+4 -4
View File
@@ -5,7 +5,7 @@
<head> <head>
<meta charset="utf-8" /> <meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>What is Reticulum? &#8212; Reticulum Network Stack 0.2.3 beta documentation</title> <title>What is Reticulum? &#8212; Reticulum Network Stack 0.2.4 beta documentation</title>
<link rel="stylesheet" type="text/css" href="_static/pygments.css" /> <link rel="stylesheet" type="text/css" href="_static/pygments.css" />
<link rel="stylesheet" type="text/css" href="_static/classic.css" /> <link rel="stylesheet" type="text/css" href="_static/classic.css" />
@@ -31,7 +31,7 @@
<li class="right" > <li class="right" >
<a href="index.html" title="Reticulum Network Stack Manual" <a href="index.html" title="Reticulum Network Stack Manual"
accesskey="P">previous</a> |</li> accesskey="P">previous</a> |</li>
<li class="nav-item nav-item-0"><a href="index.html">Reticulum Network Stack 0.2.3 beta documentation</a> &#187;</li> <li class="nav-item nav-item-0"><a href="index.html">Reticulum Network Stack 0.2.4 beta documentation</a> &#187;</li>
<li class="nav-item nav-item-this"><a href="">What is Reticulum?</a></li> <li class="nav-item nav-item-this"><a href="">What is Reticulum?</a></li>
</ul> </ul>
</div> </div>
@@ -82,7 +82,7 @@
</li> </li>
<li><p>Efficient link establishment</p> <li><p>Efficient link establishment</p>
<ul> <ul>
<li><p>Total bandwidth cost of setting up a link is only 3 packets, totalling 240 bytes</p></li> <li><p>Total bandwidth cost of setting up a link is only 3 packets, totalling 237 bytes</p></li>
<li><p>Low cost of keeping links open at only 0.62 bits per second</p></li> <li><p>Low cost of keeping links open at only 0.62 bits per second</p></li>
</ul> </ul>
</li> </li>
@@ -182,7 +182,7 @@ network, and vice versa.</p>
<li class="right" > <li class="right" >
<a href="index.html" title="Reticulum Network Stack Manual" <a href="index.html" title="Reticulum Network Stack Manual"
>previous</a> |</li> >previous</a> |</li>
<li class="nav-item nav-item-0"><a href="index.html">Reticulum Network Stack 0.2.3 beta documentation</a> &#187;</li> <li class="nav-item nav-item-0"><a href="index.html">Reticulum Network Stack 0.2.4 beta documentation</a> &#187;</li>
<li class="nav-item nav-item-this"><a href="">What is Reticulum?</a></li> <li class="nav-item nav-item-this"><a href="">What is Reticulum?</a></li>
</ul> </ul>
</div> </div>
+1 -1
View File
@@ -22,7 +22,7 @@ copyright = '2021, Mark Qvist'
author = 'Mark Qvist' author = 'Mark Qvist'
# The full version, including alpha/beta/rc tags # The full version, including alpha/beta/rc tags
release = '0.2.3 beta' release = '0.2.4 beta'
# -- General configuration --------------------------------------------------- # -- General configuration ---------------------------------------------------
+12 -4
View File
@@ -39,7 +39,7 @@ Destination
Packet Packet
------ ------
.. autoclass:: RNS.Packet .. autoclass:: RNS.Packet(destination, data, create_receipt = True)
:members: :members:
.. _api-packetreceipt: .. _api-packetreceipt:
@@ -47,7 +47,7 @@ Packet
Packet Receipt Packet Receipt
-------------- --------------
.. autoclass:: RNS.PacketReceipt .. autoclass:: RNS.PacketReceipt()
:members: :members:
.. _api-link: .. _api-link:
@@ -55,7 +55,15 @@ Packet Receipt
Link Link
---- ----
.. autoclass:: RNS.Link .. autoclass:: RNS.Link(destination, established_callback=None, closed_callback = None)
:members:
.. _api-requestreceipt:
Request Receipt
---------------
.. autoclass:: RNS.RequestReceipt()
:members: :members:
.. _api-resource: .. _api-resource:
@@ -63,7 +71,7 @@ Link
Resource Resource
-------- --------
.. autoclass:: RNS.Resource .. autoclass:: RNS.Resource(data, link, advertise=True, auto_compress=True, callback=None, progress_callback=None, timeout=None)
:members: :members:
.. _api-transport: .. _api-transport:
+2 -2
View File
@@ -429,7 +429,7 @@ terms of bandwidth, so it can be used just for a short exchange, and then recrea
also rotate encryption keys. The link can also be kept alive for longer periods of time, if this is also rotate encryption keys. The link can also be kept alive for longer periods of time, if this is
more suitable to the application. The procedure also inserts the *link id* , a hash calculated from the link request packet, into the memory of forwarding nodes, which means that the communicating nodes can thereafter reach each other simply by referring to this *link id*. more suitable to the application. The procedure also inserts the *link id* , a hash calculated from the link request packet, into the memory of forwarding nodes, which means that the communicating nodes can thereafter reach each other simply by referring to this *link id*.
The combined bandwidth cost of setting up a link is 3 packets totalling 240 bytes (more info in the The combined bandwidth cost of setting up a link is 3 packets totalling 237 bytes (more info in the
:ref:`Binary Packet Format<understanding-packetformat>` section). The amount of bandwidth used on keeping :ref:`Binary Packet Format<understanding-packetformat>` section). The amount of bandwidth used on keeping
a link open is practically negligible, at 0.62 bits per second. Even on a slow 1200 bits per second packet a link open is practically negligible, at 0.62 bits per second. Even on a slow 1200 bits per second packet
radio channel, 100 concurrent links will still leave 95% channel capacity for actual data. radio channel, 100 concurrent links will still leave 95% channel capacity for actual data.
@@ -701,5 +701,5 @@ Binary Packet Format
- Announce : 151 bytes - Announce : 151 bytes
- Link Request : 77 bytes - Link Request : 77 bytes
- Link Proof : 77 bytes - Link Proof : 77 bytes
- Link RTT packet : 86 bytes - Link RTT packet : 83 bytes
- Link keepalive : 14 bytes - Link keepalive : 14 bytes
+1 -1
View File
@@ -57,7 +57,7 @@ What does Reticulum Offer?
* Efficient link establishment * Efficient link establishment
* Total bandwidth cost of setting up a link is only 3 packets, totalling 240 bytes * Total bandwidth cost of setting up a link is only 3 packets, totalling 237 bytes
* Low cost of keeping links open at only 0.62 bits per second * Low cost of keeping links open at only 0.62 bits per second