mirror of
https://github.com/markqvist/Reticulum.git
synced 2024-11-26 23:40:18 +00:00
Resource work
This commit is contained in:
parent
bf0e22d461
commit
81804b5d19
126
RNS/Resource.py
126
RNS/Resource.py
@ -9,12 +9,12 @@ from time import sleep
|
|||||||
|
|
||||||
class Resource:
|
class Resource:
|
||||||
WINDOW_FLEXIBILITY = 4
|
WINDOW_FLEXIBILITY = 4
|
||||||
WINDOW_MIN = 1
|
WINDOW_MIN = 1
|
||||||
WINDOW_MAX = 10
|
WINDOW_MAX = 10
|
||||||
WINDOW = 4
|
WINDOW = 4
|
||||||
MAPHASH_LEN = 4
|
MAPHASH_LEN = 4
|
||||||
SDU = RNS.Packet.MDU
|
SDU = RNS.Packet.MDU
|
||||||
RANDOM_HASH_SIZE = 4
|
RANDOM_HASH_SIZE = 4
|
||||||
|
|
||||||
# This is an indication of what the
|
# This is an indication of what the
|
||||||
# maximum size a resource should be, if
|
# maximum size a resource should be, if
|
||||||
@ -34,7 +34,7 @@ class Resource:
|
|||||||
# TODO: Should be allocated more
|
# TODO: Should be allocated more
|
||||||
# intelligently
|
# intelligently
|
||||||
# TODO: Set higher
|
# TODO: Set higher
|
||||||
MAX_RETRIES = 5
|
MAX_RETRIES = 5
|
||||||
SENDER_GRACE_TIME = 10
|
SENDER_GRACE_TIME = 10
|
||||||
RETRY_GRACE_TIME = 0.25
|
RETRY_GRACE_TIME = 0.25
|
||||||
|
|
||||||
@ -47,7 +47,7 @@ class Resource:
|
|||||||
ADVERTISED = 0x02
|
ADVERTISED = 0x02
|
||||||
TRANSFERRING = 0x03
|
TRANSFERRING = 0x03
|
||||||
AWAITING_PROOF = 0x04
|
AWAITING_PROOF = 0x04
|
||||||
ASSEMBLING = 0x05
|
ASSEMBLING = 0x05
|
||||||
COMPLETE = 0x06
|
COMPLETE = 0x06
|
||||||
FAILED = 0x07
|
FAILED = 0x07
|
||||||
CORRUPT = 0x08
|
CORRUPT = 0x08
|
||||||
@ -60,31 +60,31 @@ class Resource:
|
|||||||
resource = Resource(None, advertisement_packet.link)
|
resource = Resource(None, advertisement_packet.link)
|
||||||
resource.status = Resource.TRANSFERRING
|
resource.status = Resource.TRANSFERRING
|
||||||
|
|
||||||
resource.flags = adv.f
|
resource.flags = adv.f
|
||||||
resource.size = adv.t
|
resource.size = adv.t
|
||||||
resource.uncompressed_size = adv.d
|
resource.uncompressed_size = adv.d
|
||||||
resource.hash = adv.h
|
resource.hash = adv.h
|
||||||
resource.original_hash = adv.o
|
resource.original_hash = adv.o
|
||||||
resource.random_hash = adv.r
|
resource.random_hash = adv.r
|
||||||
resource.hashmap_raw = adv.m
|
resource.hashmap_raw = adv.m
|
||||||
resource.encrypted = True if resource.flags & 0x01 else False
|
resource.encrypted = True if resource.flags & 0x01 else False
|
||||||
resource.compressed = True if resource.flags >> 1 & 0x01 else False
|
resource.compressed = True if resource.flags >> 1 & 0x01 else False
|
||||||
resource.initiator = False
|
resource.initiator = False
|
||||||
resource.callback = callback
|
resource.callback = callback
|
||||||
resource.__progress_callback = progress_callback
|
resource.__progress_callback = progress_callback
|
||||||
resource.total_parts = int(math.ceil(resource.size/float(Resource.SDU)))
|
resource.total_parts = int(math.ceil(resource.size/float(Resource.SDU)))
|
||||||
resource.received_count = 0
|
resource.received_count = 0
|
||||||
resource.outstanding_parts = 0
|
resource.outstanding_parts = 0
|
||||||
resource.parts = [None] * resource.total_parts
|
resource.parts = [None] * resource.total_parts
|
||||||
resource.window = Resource.WINDOW
|
resource.window = Resource.WINDOW
|
||||||
resource.window_max = Resource.WINDOW_MAX
|
resource.window_max = Resource.WINDOW_MAX
|
||||||
resource.window_min = Resource.WINDOW_MIN
|
resource.window_min = Resource.WINDOW_MIN
|
||||||
resource.window_flexibility = Resource.WINDOW_FLEXIBILITY
|
resource.window_flexibility = Resource.WINDOW_FLEXIBILITY
|
||||||
resource.last_activity = time.time()
|
resource.last_activity = time.time()
|
||||||
|
|
||||||
resource.storagepath = RNS.Reticulum.resourcepath+"/"+resource.original_hash.hex()
|
resource.storagepath = RNS.Reticulum.resourcepath+"/"+resource.original_hash.hex()
|
||||||
resource.segment_index = adv.i
|
resource.segment_index = adv.i
|
||||||
resource.total_segments = adv.l
|
resource.total_segments = adv.l
|
||||||
if adv.l > 1:
|
if adv.l > 1:
|
||||||
resource.split = True
|
resource.split = True
|
||||||
else:
|
else:
|
||||||
@ -122,19 +122,20 @@ class Resource:
|
|||||||
resource_data = None
|
resource_data = None
|
||||||
if hasattr(data, "read"):
|
if hasattr(data, "read"):
|
||||||
data_size = os.stat(data.name).st_size
|
data_size = os.stat(data.name).st_size
|
||||||
|
self.grand_total_parts = math.ceil(data_size/Resource.SDU)
|
||||||
|
|
||||||
if data_size <= Resource.MAX_EFFICIENT_SIZE:
|
if data_size <= Resource.MAX_EFFICIENT_SIZE:
|
||||||
self.total_segments = 1
|
self.total_segments = 1
|
||||||
self.segment_index = 1
|
self.segment_index = 1
|
||||||
self.split = False
|
self.split = False
|
||||||
resource_data = data.read()
|
resource_data = data.read()
|
||||||
data.close()
|
data.close()
|
||||||
else:
|
else:
|
||||||
self.total_segments = ((data_size-1)//Resource.MAX_EFFICIENT_SIZE)+1
|
self.total_segments = ((data_size-1)//Resource.MAX_EFFICIENT_SIZE)+1
|
||||||
self.segment_index = segment_index
|
self.segment_index = segment_index
|
||||||
self.split = True
|
self.split = True
|
||||||
seek_index = segment_index-1
|
seek_index = segment_index-1
|
||||||
seek_position = seek_index*Resource.MAX_EFFICIENT_SIZE
|
seek_position = seek_index*Resource.MAX_EFFICIENT_SIZE
|
||||||
|
|
||||||
data.seek(seek_position)
|
data.seek(seek_position)
|
||||||
resource_data = data.read(Resource.MAX_EFFICIENT_SIZE)
|
resource_data = data.read(Resource.MAX_EFFICIENT_SIZE)
|
||||||
@ -142,10 +143,12 @@ class Resource:
|
|||||||
|
|
||||||
elif isinstance(data, bytes):
|
elif isinstance(data, bytes):
|
||||||
data_size = len(data)
|
data_size = len(data)
|
||||||
|
self.grand_total_parts = math.ceil(data_size/Resource.SDU)
|
||||||
|
|
||||||
resource_data = data
|
resource_data = data
|
||||||
self.total_segments = 1
|
self.total_segments = 1
|
||||||
self.segment_index = 1
|
self.segment_index = 1
|
||||||
self.split = False
|
self.split = False
|
||||||
|
|
||||||
elif data == None:
|
elif data == None:
|
||||||
pass
|
pass
|
||||||
@ -167,13 +170,12 @@ class Resource:
|
|||||||
self.__watchdog_job_id = 0
|
self.__watchdog_job_id = 0
|
||||||
self.__progress_callback = progress_callback
|
self.__progress_callback = progress_callback
|
||||||
self.rtt = None
|
self.rtt = None
|
||||||
self.grand_total_parts = math.ceil(data_size/Resource.SDU)
|
|
||||||
|
|
||||||
self.receiver_min_consecutive_height = 0
|
self.receiver_min_consecutive_height = 0
|
||||||
|
|
||||||
if data != None:
|
if data != None:
|
||||||
self.initiator = True
|
self.initiator = True
|
||||||
self.callback = callback
|
self.callback = callback
|
||||||
self.uncompressed_data = data
|
self.uncompressed_data = data
|
||||||
|
|
||||||
compression_began = time.time()
|
compression_began = time.time()
|
||||||
@ -228,14 +230,14 @@ class Resource:
|
|||||||
hashmap_computation_began = time.time()
|
hashmap_computation_began = time.time()
|
||||||
RNS.log("Starting resource hashmap computation with "+str(hashmap_entries)+" entries...", RNS.LOG_DEBUG)
|
RNS.log("Starting resource hashmap computation with "+str(hashmap_entries)+" entries...", RNS.LOG_DEBUG)
|
||||||
|
|
||||||
self.random_hash = RNS.Identity.getRandomHash()[:Resource.RANDOM_HASH_SIZE]
|
self.random_hash = RNS.Identity.getRandomHash()[:Resource.RANDOM_HASH_SIZE]
|
||||||
self.hash = RNS.Identity.fullHash(data+self.random_hash)
|
self.hash = RNS.Identity.fullHash(data+self.random_hash)
|
||||||
self.expected_proof = RNS.Identity.fullHash(data+self.hash)
|
self.expected_proof = RNS.Identity.fullHash(data+self.hash)
|
||||||
|
|
||||||
if original_hash == None:
|
if original_hash == None:
|
||||||
self.original_hash = self.hash
|
self.original_hash = self.hash
|
||||||
else:
|
else:
|
||||||
self.original_hash = original_hash
|
self.original_hash = original_hash
|
||||||
|
|
||||||
self.parts = []
|
self.parts = []
|
||||||
self.hashmap = b""
|
self.hashmap = b""
|
||||||
@ -717,19 +719,21 @@ class Resource:
|
|||||||
|
|
||||||
def progress(self):
|
def progress(self):
|
||||||
if self.initiator:
|
if self.initiator:
|
||||||
|
# TODO: Remove
|
||||||
|
# progress = self.sent_parts / len(self.parts)
|
||||||
self.processed_parts = (self.segment_index-1)*math.ceil(Resource.MAX_EFFICIENT_SIZE/Resource.SDU)
|
self.processed_parts = (self.segment_index-1)*math.ceil(Resource.MAX_EFFICIENT_SIZE/Resource.SDU)
|
||||||
self.processed_parts += self.sent_parts
|
self.processed_parts += self.sent_parts
|
||||||
self.progress_total_parts = float(self.grand_total_parts)
|
self.progress_total_parts = float(self.grand_total_parts)
|
||||||
else:
|
else:
|
||||||
self.processed_parts = (self.segment_index-1)*math.ceil(Resource.MAX_EFFICIENT_SIZE/Resource.SDU)
|
self.processed_parts = (self.segment_index-1)*math.ceil(Resource.MAX_EFFICIENT_SIZE/Resource.SDU)
|
||||||
self.processed_parts += self.received_count
|
self.processed_parts += self.received_count
|
||||||
if self.split:
|
if self.split:
|
||||||
self.progress_total_parts = float((self.total_segments-1)*math.ceil(Resource.MAX_EFFICIENT_SIZE/Resource.SDU)+self.total_parts)
|
self.progress_total_parts = float((self.total_segments-1)*math.ceil(Resource.MAX_EFFICIENT_SIZE/Resource.SDU)+self.total_parts)
|
||||||
else:
|
else:
|
||||||
self.progress_total_parts = float(self.total_parts)
|
self.progress_total_parts = float(self.total_parts)
|
||||||
|
|
||||||
|
|
||||||
progress = self.processed_parts / self.progress_total_parts
|
progress = self.processed_parts / self.progress_total_parts
|
||||||
return progress
|
return progress
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
@ -737,23 +741,23 @@ class Resource:
|
|||||||
|
|
||||||
|
|
||||||
class ResourceAdvertisement:
|
class ResourceAdvertisement:
|
||||||
HASHMAP_MAX_LEN = 75
|
HASHMAP_MAX_LEN = 75
|
||||||
COLLISION_GUARD_SIZE = 2*Resource.WINDOW_MAX+HASHMAP_MAX_LEN
|
COLLISION_GUARD_SIZE = 2*Resource.WINDOW_MAX+HASHMAP_MAX_LEN
|
||||||
|
|
||||||
def __init__(self, resource=None):
|
def __init__(self, resource=None):
|
||||||
if resource != None:
|
if resource != None:
|
||||||
self.t = resource.size # Transfer size
|
self.t = resource.size # Transfer size
|
||||||
self.d = resource.uncompressed_size # Data size
|
self.d = resource.uncompressed_size # Data size
|
||||||
self.n = len(resource.parts) # Number of parts
|
self.n = len(resource.parts) # Number of parts
|
||||||
self.h = resource.hash # Resource hash
|
self.h = resource.hash # Resource hash
|
||||||
self.r = resource.random_hash # Resource random hash
|
self.r = resource.random_hash # Resource random hash
|
||||||
self.o = resource.original_hash # First-segment hash
|
self.o = resource.original_hash # First-segment hash
|
||||||
self.m = resource.hashmap # Resource hashmap
|
self.m = resource.hashmap # Resource hashmap
|
||||||
self.c = resource.compressed # Compression flag
|
self.c = resource.compressed # Compression flag
|
||||||
self.e = resource.encrypted # Encryption flag
|
self.e = resource.encrypted # Encryption flag
|
||||||
self.s = resource.split # Split flag
|
self.s = resource.split # Split flag
|
||||||
self.i = resource.segment_index # Segment index
|
self.i = resource.segment_index # Segment index
|
||||||
self.l = resource.total_segments # Total segments
|
self.l = resource.total_segments # Total segments
|
||||||
self.f = 0x00 | self.s << 2 | self.c << 1 | self.e # Flags
|
self.f = 0x00 | self.s << 2 | self.c << 1 | self.e # Flags
|
||||||
|
|
||||||
def pack(self, segment=0):
|
def pack(self, segment=0):
|
||||||
@ -770,7 +774,7 @@ class ResourceAdvertisement:
|
|||||||
"n": self.n, # Number of parts
|
"n": self.n, # Number of parts
|
||||||
"h": self.h, # Resource hash
|
"h": self.h, # Resource hash
|
||||||
"r": self.r, # Resource random hash
|
"r": self.r, # Resource random hash
|
||||||
"o": self.o, # Original hash
|
"o": self.o, # Original hash
|
||||||
"i": self.i, # Segment index
|
"i": self.i, # Segment index
|
||||||
"l": self.l, # Total segments
|
"l": self.l, # Total segments
|
||||||
"f": self.f, # Resource flags
|
"f": self.f, # Resource flags
|
||||||
|
Loading…
Reference in New Issue
Block a user