mirror of
https://github.com/markqvist/Reticulum.git
synced 2026-07-09 18:18:12 -07:00
Compare commits
26 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| c7e5f4612a | |||
| f80e09cb5c | |||
| 91d94f2f6f | |||
| 53ca86ebfc | |||
| 534bb28900 | |||
| 0de5ec73ad | |||
| c0f627b50b | |||
| 5629a062a5 | |||
| 83232f0446 | |||
| aa794514b3 | |||
| 07cf180ea8 | |||
| 42a3d23e99 | |||
| d28c888d1c | |||
| 58d48c18f4 | |||
| ecf0c55fd6 | |||
| 32e4c262ef | |||
| f87a6a57df | |||
| 6373f159f8 | |||
| ad9f548eeb | |||
| 425f0153d0 | |||
| cd9daaefee | |||
| 0fe76d50f6 | |||
| 9562803bb3 | |||
| e9c89209c7 | |||
| cd8de64201 | |||
| 40f7a6d359 |
@@ -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)
|
||||||
|
|||||||
@@ -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
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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"))
|
||||||
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -1 +1 @@
|
|||||||
__version__ = "0.2.3"
|
__version__ = "0.2.4"
|
||||||
Vendored
+1
-1
@@ -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
|
||||||
|
|||||||
Vendored
+998
@@ -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,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
|
||||||
|
|||||||
@@ -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:
|
||||||
|
|||||||
@@ -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
|
||||||
@@ -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,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',
|
||||||
|
|||||||
@@ -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 — Reticulum Network Stack 0.2.3 beta documentation</title>
|
<title>Examples — 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> »</li>
|
<li class="nav-item nav-item-0"><a href="index.html">Reticulum Network Stack 0.2.4 beta documentation</a> »</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">""</span><span class="p">)</span>
|
<span class="nb">print</span><span class="p">(</span><span class="s2">""</span><span class="p">)</span>
|
||||||
<span class="k">while</span> <span class="n">menu_mode</span> <span class="o">==</span> <span class="s2">"downloading"</span><span class="p">:</span>
|
<span class="k">while</span> <span class="n">menu_mode</span> <span class="o">==</span> <span class="s2">"downloading"</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">"</span><span class="se">\r</span><span class="s2">Progress: "</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">" % "</span><span class="p">),</span> <span class="n">end</span><span class="o">=</span><span class="s1">' '</span><span class="p">)</span>
|
<span class="nb">print</span><span class="p">((</span><span class="s2">"</span><span class="se">\r</span><span class="s2">Progress: "</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">" % "</span><span class="p">),</span> <span class="n">end</span><span class="o">=</span><span class="s1">' '</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> »</li>
|
<li class="nav-item nav-item-0"><a href="index.html">Reticulum Network Stack 0.2.4 beta documentation</a> »</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
@@ -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 — Reticulum Network Stack 0.2.3 beta documentation</title>
|
<title>Index — 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> »</li>
|
<li class="nav-item nav-item-0"><a href="index.html">Reticulum Network Stack 0.2.4 beta documentation</a> »</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> »</li>
|
<li class="nav-item nav-item-0"><a href="index.html">Reticulum Network Stack 0.2.4 beta documentation</a> »</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>
|
||||||
|
|||||||
@@ -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 — Reticulum Network Stack 0.2.3 beta documentation</title>
|
<title>Getting Started Fast — 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> »</li>
|
<li class="nav-item nav-item-0"><a href="index.html">Reticulum Network Stack 0.2.4 beta documentation</a> »</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 @@ don’t 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> »</li>
|
<li class="nav-item nav-item-0"><a href="index.html">Reticulum Network Stack 0.2.4 beta documentation</a> »</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>
|
||||||
|
|||||||
@@ -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 — Reticulum Network Stack 0.2.3 beta documentation</title>
|
<title>Reticulum Network Stack Manual — 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> »</li>
|
<li class="nav-item nav-item-0"><a href="#">Reticulum Network Stack 0.2.4 beta documentation</a> »</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> »</li>
|
<li class="nav-item nav-item-0"><a href="#">Reticulum Network Stack 0.2.4 beta documentation</a> »</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
@@ -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 — Reticulum Network Stack 0.2.3 beta documentation</title>
|
<title>API Reference — 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> »</li>
|
<li class="nav-item nav-item-0"><a href="index.html">Reticulum Network Stack 0.2.4 beta documentation</a> »</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> »</li>
|
<li class="nav-item nav-item-0"><a href="index.html">Reticulum Network Stack 0.2.4 beta documentation</a> »</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>
|
||||||
|
|||||||
@@ -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 — Reticulum Network Stack 0.2.3 beta documentation</title>
|
<title>Search — 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> »</li>
|
<li class="nav-item nav-item-0"><a href="index.html">Reticulum Network Stack 0.2.4 beta documentation</a> »</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> »</li>
|
<li class="nav-item nav-item-0"><a href="index.html">Reticulum Network Stack 0.2.4 beta documentation</a> »</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,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 — Reticulum Network Stack 0.2.3 beta documentation</title>
|
<title>Understanding Reticulum — 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> »</li>
|
<li class="nav-item nav-item-0"><a href="index.html">Reticulum Network Stack 0.2.4 beta documentation</a> »</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> »</li>
|
<li class="nav-item nav-item-0"><a href="index.html">Reticulum Network Stack 0.2.4 beta documentation</a> »</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>
|
||||||
|
|||||||
@@ -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? — Reticulum Network Stack 0.2.3 beta documentation</title>
|
<title>What is Reticulum? — 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> »</li>
|
<li class="nav-item nav-item-0"><a href="index.html">Reticulum Network Stack 0.2.4 beta documentation</a> »</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> »</li>
|
<li class="nav-item nav-item-0"><a href="index.html">Reticulum Network Stack 0.2.4 beta documentation</a> »</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
@@ -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 ---------------------------------------------------
|
||||||
|
|||||||
@@ -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:
|
||||||
|
|||||||
@@ -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
|
||||||
@@ -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
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user