From d68cfaa8f79af3fb1cdeb7b420754717596f1d09 Mon Sep 17 00:00:00 2001 From: Mark Qvist Date: Thu, 20 May 2021 20:32:08 +0200 Subject: [PATCH] Optimised link establishment --- README.md | 2 +- RNS/Destination.py | 17 ++++++------ RNS/Link.py | 30 ++++++++++----------- RNS/Packet.py | 3 +++ docs/Reticulum Manual.pdf | Bin 441665 -> 441829 bytes docs/manual/_sources/understanding.rst.txt | 6 ++--- docs/manual/_sources/whatis.rst.txt | 2 +- docs/manual/reference.html | 2 +- docs/manual/searchindex.js | 2 +- docs/manual/understanding.html | 6 ++--- docs/manual/whatis.html | 2 +- docs/source/understanding.rst | 6 ++--- docs/source/whatis.rst | 2 +- 13 files changed, 42 insertions(+), 38 deletions(-) diff --git a/README.md b/README.md index 04c49a1..b32ab8f 100755 --- a/README.md +++ b/README.md @@ -33,7 +33,7 @@ For more info, see [unsigned.io/projects/reticulum](https://unsigned.io/projects - Sequencing, transfer coordination and checksumming is automatic - The API is very easy to use, and provides transfer progress - Efficient link establishment - - Total bandwidth cost of setting up a link is 3 packets totalling 409 bytes + - Total bandwidth cost of setting up a link is 3 packets totalling 240 bytes - Low cost of keeping links open at only 0.62 bits per second ## Where can Reticulum be used? diff --git a/RNS/Destination.py b/RNS/Destination.py index f4798ad..f8b24b3 100755 --- a/RNS/Destination.py +++ b/RNS/Destination.py @@ -209,14 +209,15 @@ class Destination: self.proof_strategy = proof_strategy def receive(self, packet): - plaintext = self.decrypt(packet.data) - if plaintext != None: - if packet.packet_type == RNS.Packet.LINKREQUEST: - self.incoming_link_request(plaintext, packet) - - if packet.packet_type == RNS.Packet.DATA: - if self.callbacks.packet != None: - self.callbacks.packet(plaintext, packet) + if packet.packet_type == RNS.Packet.LINKREQUEST: + plaintext = packet.data + self.incoming_link_request(plaintext, packet) + else: + plaintext = self.decrypt(packet.data) + if plaintext != None: + if packet.packet_type == RNS.Packet.DATA: + if self.callbacks.packet != None: + self.callbacks.packet(plaintext, packet) def incoming_link_request(self, data, packet): link = RNS.Link.validate_request(self, data, packet) diff --git a/RNS/Link.py b/RNS/Link.py index eacec7e..abb83e4 100644 --- a/RNS/Link.py +++ b/RNS/Link.py @@ -52,7 +52,7 @@ class Link: """ TIMEOUT_FACTOR = 3 STALE_GRACE = 2 - KEEPALIVE = 180 + KEEPALIVE = 360 """ Interval for sending keep-alive packets on established links in seconds. """ @@ -128,14 +128,15 @@ class Link: self.__encryption_disabled = False if self.destination == None: self.initiator = False + self.prv = self.owner.identity.prv + self.sig_prv = self.owner.identity.sig_prv else: self.initiator = True + self.prv = X25519PrivateKey.generate() + self.sig_prv = Ed25519PrivateKey.generate() self.fernet = None - self.prv = X25519PrivateKey.generate() - self.sig_prv = Ed25519PrivateKey.generate() - self.pub = self.prv.public_key() self.pub_bytes = self.pub.public_bytes( encoding=serialization.Encoding.Raw, @@ -155,10 +156,14 @@ class Link: self.load_peer(peer_pub_bytes, peer_sig_pub_bytes) if (self.initiator): + peer_pub_bytes = self.destination.identity.get_public_key()[:Link.ECPUBSIZE//2] + peer_sig_pub_bytes = self.destination.identity.get_public_key()[Link.ECPUBSIZE//2:Link.ECPUBSIZE] self.request_data = self.pub_bytes+self.sig_pub_bytes self.packet = RNS.Packet(destination, self.request_data, packet_type=RNS.Packet.LINKREQUEST) self.packet.pack() self.set_link_id(self.packet) + self.load_peer(peer_pub_bytes, peer_sig_pub_bytes) + self.handshake() RNS.Transport.register_link(self) self.request_time = time.time() self.start_watchdog() @@ -195,7 +200,7 @@ class Link: signed_data = self.link_id+self.pub_bytes+self.sig_pub_bytes signature = self.owner.identity.sign(signed_data) - proof_data = self.pub_bytes+self.sig_pub_bytes+signature + proof_data = signature proof = RNS.Packet(self, proof_data, packet_type=RNS.Packet.PROOF, context=RNS.Packet.LRPROOF) proof.send() self.had_outbound() @@ -214,15 +219,11 @@ class Link: self.had_outbound() def validate_proof(self, packet): - if self.initiator and len(packet.data) == Link.ECPUBSIZE+RNS.Identity.KEYSIZE//8: - peer_pub_bytes = packet.data[:Link.ECPUBSIZE//2] - peer_sig_pub_bytes = packet.data[Link.ECPUBSIZE//2:Link.ECPUBSIZE] - signed_data = self.link_id+peer_pub_bytes+peer_sig_pub_bytes - signature = packet.data[Link.ECPUBSIZE:RNS.Identity.KEYSIZE//8+Link.ECPUBSIZE] - + 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 + signature = packet.data[:RNS.Identity.SIGLENGTH//8] + if self.destination.identity.validate(signature, signed_data): - self.load_peer(peer_pub_bytes, peer_sig_pub_bytes) - self.handshake() self.rtt = time.time() - self.request_time self.attached_interface = packet.receiving_interface RNS.Transport.activate_link(self) @@ -258,8 +259,7 @@ class Link: if self.owner.callbacks.link_established != None: self.owner.callbacks.link_established(self) except Exception as e: - RNS.log("Error occurred while processing RTT packet, tearing down link", RNS.LOG_ERROR) - traceback.print_exc() + RNS.log("Error occurred while processing RTT packet, tearing down link. The contained exception was: "+str(e), RNS.LOG_ERROR) self.teardown() def get_salt(self): diff --git a/RNS/Packet.py b/RNS/Packet.py index 8ee68a3..faf2235 100755 --- a/RNS/Packet.py +++ b/RNS/Packet.py @@ -143,6 +143,9 @@ class Packet: if self.packet_type == Packet.ANNOUNCE: # Announce packets are not encrypted self.ciphertext = self.data + elif self.packet_type == Packet.LINKREQUEST: + # Link request packets are not encrypted + self.ciphertext = self.data elif self.packet_type == Packet.PROOF and self.context == Packet.RESOURCE_PRF: # Resource proofs are not encrypted self.ciphertext = self.data diff --git a/docs/Reticulum Manual.pdf b/docs/Reticulum Manual.pdf index 3cc83c025239a044d2ccdaa95870ee86e5d31c1f..4ac9eaf171d6bbdd4a483578b63759cf062c45d1 100644 GIT binary patch delta 18187 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 delta 18050 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 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 radio channel, 100 concurrent links will still leave 95% channel capacity for actual data. @@ -699,7 +699,7 @@ Binary Packet Format - Path Request : 33 bytes - Announce : 151 bytes - - Link Request : 182 bytes - - Link Proof : 141 bytes + - Link Request : 77 bytes + - Link Proof : 77 bytes - Link RTT packet : 86 bytes - Link keepalive : 14 bytes \ No newline at end of file diff --git a/docs/manual/_sources/whatis.rst.txt b/docs/manual/_sources/whatis.rst.txt index eb15688..66f1b8e 100644 --- a/docs/manual/_sources/whatis.rst.txt +++ b/docs/manual/_sources/whatis.rst.txt @@ -55,7 +55,7 @@ What does Reticulum Offer? * Efficient link establishment - * Total bandwidth cost of setting up a link is only 409 bytes + * Total bandwidth cost of setting up a link is only 3 packets, totalling 240 bytes * Low cost of keeping links open at only 0.62 bits per second diff --git a/docs/manual/reference.html b/docs/manual/reference.html index 982dfb2..d1d4341 100644 --- a/docs/manual/reference.html +++ b/docs/manual/reference.html @@ -767,7 +767,7 @@ from a the send() method of a
-KEEPALIVE = 180
+KEEPALIVE = 360

Interval for sending keep-alive packets on established links in seconds.

diff --git a/docs/manual/searchindex.js b/docs/manual/searchindex.js index 3205bf9..81ddabd 100644 --- a/docs/manual/searchindex.js +++ b/docs/manual/searchindex.js @@ -1 +1 @@ -Search.setIndex({docnames:["examples","gettingstartedfast","index","reference","understanding","whatis"],envversion:{"sphinx.domains.c":2,"sphinx.domains.changeset":1,"sphinx.domains.citation":1,"sphinx.domains.cpp":3,"sphinx.domains.index":1,"sphinx.domains.javascript":2,"sphinx.domains.math":2,"sphinx.domains.python":3,"sphinx.domains.rst":2,"sphinx.domains.std":2,sphinx:56},filenames:["examples.rst","gettingstartedfast.rst","index.rst","reference.rst","understanding.rst","whatis.rst"],objects:{"RNS.Destination":{announce:[3,1,1,""],app_and_aspects_from_name:[3,1,1,""],clear_default_app_data:[3,1,1,""],create_keys:[3,1,1,""],decrypt:[3,1,1,""],encrypt:[3,1,1,""],full_name:[3,1,1,""],get_private_key:[3,1,1,""],hash:[3,1,1,""],hash_from_name_and_identity:[3,1,1,""],load_private_key:[3,1,1,""],set_default_app_data:[3,1,1,""],set_link_established_callback:[3,1,1,""],set_packet_callback:[3,1,1,""],set_proof_requested_callback:[3,1,1,""],set_proof_strategy:[3,1,1,""],sign:[3,1,1,""]},"RNS.Identity":{CURVE:[3,2,1,""],KEYSIZE:[3,2,1,""],TRUNCATED_HASHLENGTH:[3,2,1,""],decrypt:[3,1,1,""],encrypt:[3,1,1,""],from_bytes:[3,1,1,""],from_file:[3,1,1,""],full_hash:[3,1,1,""],get_private_key:[3,1,1,""],get_public_key:[3,1,1,""],get_random_hash:[3,1,1,""],load_private_key:[3,1,1,""],load_public_key:[3,1,1,""],recall:[3,1,1,""],recall_app_data:[3,1,1,""],sign:[3,1,1,""],to_file:[3,1,1,""],truncated_hash:[3,1,1,""],validate:[3,1,1,""]},"RNS.Link":{CURVE:[3,2,1,""],DEFAULT_TIMEOUT:[3,2,1,""],KEEPALIVE:[3,2,1,""],disable_encryption:[3,1,1,""],inactive_for:[3,1,1,""],no_inbound_for:[3,1,1,""],no_outbound_for:[3,1,1,""],set_packet_callback:[3,1,1,""],set_resource_callback:[3,1,1,""],set_resource_concluded_callback:[3,1,1,""],set_resource_started_callback:[3,1,1,""],set_resource_strategy:[3,1,1,""],teardown:[3,1,1,""]},"RNS.Packet":{ENCRYPTED_MDU:[3,2,1,""],PLAIN_MDU:[3,2,1,""],resend:[3,1,1,""],send:[3,1,1,""]},"RNS.PacketReceipt":{get_rtt:[3,1,1,""],get_status:[3,1,1,""],set_delivery_callback:[3,1,1,""],set_timeout:[3,1,1,""],set_timeout_callback:[3,1,1,""]},"RNS.Resource":{advertise:[3,1,1,""],cancel:[3,1,1,""],progress:[3,1,1,""]},"RNS.Reticulum":{should_allow_unencrypted:[3,1,1,""],should_use_implicit_proof:[3,1,1,""],transport_enabled:[3,1,1,""]},"RNS.Transport":{deregister_announce_handler:[3,1,1,""],has_path:[3,1,1,""],register_announce_handler:[3,1,1,""],request_path:[3,1,1,""]},RNS:{Destination:[3,0,1,""],Identity:[3,0,1,""],Link:[3,0,1,""],Packet:[3,0,1,""],PacketReceipt:[3,0,1,""],Resource:[3,0,1,""],Reticulum:[3,0,1,""],Transport:[3,0,1,""]}},objnames:{"0":["py","class","Python class"],"1":["py","method","Python method"],"2":["py","attribute","Python attribute"]},objtypes:{"0":"py:class","1":"py:method","2":"py:attribute"},terms:{"0":[0,3,4,5],"00":4,"000":[4,5],"00000000":4,"00000100":4,"00000111":4,"01":4,"01010000":4,"05":0,"1":[0,3,4,5],"10":[0,4],"100":[0,4],"1000":[0,4],"1024":0,"11":4,"1200":4,"128":[4,5],"14":4,"141":4,"15":[3,4],"151":4,"18":4,"180":[3,4],"182":4,"2":[0,4],"20":[0,4],"205":[],"25":[0,5],"256":[3,4],"270":4,"2f":0,"3":[0,4,5],"323":[],"33":4,"34":4,"3600":0,"383":3,"3e12fc71692f8ec47bc5":1,"4":4,"409":[4,5],"430":4,"45":0,"477":[3,4],"5":[0,4],"500":[4,5],"512":3,"60":0,"62":[4,5],"7":4,"8":0,"80":[3,4],"80e29bf7cccaf31431b3":4,"86":4,"868":4,"900":4,"95":4,"abstract":4,"break":[4,5],"byte":[0,3,4,5],"case":[1,4],"class":[0,2,5],"default":[0,3,4],"do":[0,1,4,5],"float":[0,3],"function":[0,2,3,5],"import":[0,1,4],"int":0,"long":[0,4],"new":[0,3,4],"public":[0,2,3],"return":[0,3],"short":4,"static":3,"throw":3,"true":[0,3],"try":[0,2],"while":[0,3,4,5],A:[0,3,4,5],And:0,As:[3,4,5],At:4,Be:3,But:4,By:[0,4],For:[3,4],IN:[0,3],If:[0,1,3,4,5],In:[0,1,4,5],It:[0,3,4,5],No:[4,5],One:3,Or:4,That:4,The:[0,1,2,3,5],There:[4,5],These:4,To:[0,4,5],Will:3,With:4,_:4,__:4,______:4,_______:4,________:4,________________:4,__init__:0,__main__:0,__name__:0,_exit:0,ab:0,abl:[0,3,4],about:[0,3,4],abov:[1,4],accept:[3,4],accept_al:[0,3],accept_app:3,accept_non:3,access:[3,4],accord:4,accordingli:0,acheiv:4,achiev:[3,4],acknowledg:5,act:[3,4],action:0,activ:[0,3,4],actor:4,actual:[0,1,4],ad:[0,3,4,5],add:0,add_argu:0,addit:[4,5],addr1:4,addr2:4,address:[0,3,4,5],adress:[0,3,5],advantag:3,advertis:[0,3],advis:4,ae:[4,5],after:[0,4],again:[1,4],against:4,agent:4,agnost:4,agnostic:4,aim:[2,4],aliv:[3,4],all:[0,2,3,4,5],allow:[0,3,4,5],almost:4,along:[3,4],alreadi:[0,4],also:[0,3,4,5],alter:4,altern:0,although:5,alwai:[3,4],amateur:5,amount:[3,4,5],an:[0,1,3,4,5],ani:[0,1,3,4,5],announc:[2,3],announce_handl:0,announced_ident:[0,3],announceloop:0,announcesampl:0,anonym:4,anoth:[1,3,4],answer:4,anyon:[0,3,4],anyth:4,anywher:0,apart:4,api:[1,2,4,5],app:[0,3,4],app_and_aspects_from_nam:3,app_data:[0,3],app_nam:[0,3],app_timeout:0,append:[0,4],appli:4,applic:[0,3,4],approv:4,approxim:4,ar:[0,3,4,5],arbitrari:[3,4],arbritrari:5,area:5,arg:0,argon:0,argpars:0,argument:[0,3],argumentpars:0,around:4,arriv:[0,4],ask:[0,3],aspect:[0,3,4],aspect_filt:[0,3],assign:4,associ:[1,3,4],assum:4,asymmetr:5,attached_interfac:3,attribut:3,audit:5,authent:[4,5],author:4,auto:[3,4],auto_compress:3,autoconfigur:5,autom:4,automat:[0,3,4,5],autonom:4,autoomat:0,avail:[0,4,5],averag:4,avoid:4,awai:4,awar:4,ax:5,b:0,back:[0,4,5],band:4,bandwidth:[4,5],bare:0,barrier:4,base:[2,4,5],basi:[3,4,5],basic:[0,1,2],baud:4,becaus:4,becom:0,been:[0,3,4,5],befor:[0,3,4],begin:[0,3],begun:3,behind:4,being:4,belief:4,below:1,best:[1,4,5],beta:5,between:[0,3,4],bgp:4,bi:4,bidirect:4,binari:[0,2],bit:[3,4,5],blob:[0,4],both:[3,4,5],bp:4,briefli:4,broadcast:[2,3,4],broadcast_destin:0,broadcastloop:0,bug:5,build:[0,4,5],built:[1,4,5],bundl:0,c:[0,4],cad:4,calcul:4,call:[0,3,4,5],callabl:3,callback:[0,3],can:[0,1,2,3,4],cancel:3,cannot:0,capac:4,carambola:0,care:[3,4,5],carri:[3,4],carrier:5,caveat:2,cb:4,cbc:5,cd:1,censor:4,censorship:4,central:4,certain:[0,4],challeng:4,chang:[0,1,4,5],channel:[0,4,5],channelarg:0,chapter:[1,4],charact:0,characterist:4,cheap:4,check:0,checksum:[3,5],choos:0,chose:4,chunk:0,ciphertext:3,ciphertext_token:3,cl:0,clear:[0,3,4],clear_default_app_data:3,clear_screen:0,client:[0,1,3],client_connect:0,client_disconnect:0,client_loop:0,client_packet_receiv:0,client_request:0,clone:1,close:[0,3],closer:4,cluster:4,code:[0,4],com:[0,1],combin:4,come:4,command:[0,1],common:4,commun:[0,1,3,4,5],compat:4,complet:[0,1,3,4,5],compon:4,compos:4,compress:[0,3,4],comput:[1,4],concaten:3,concept:4,conclud:[0,3],concurr:4,condit:4,config:[0,1],configarg:0,configdir:3,configpath:0,configur:[0,3,4,5],confirm:[4,5],connect:[0,3,4,5],consequ:4,consid:[4,5],consist:4,constant:[3,4],construct:4,contact:4,contain:[0,3,4],content:[],context:[3,4],control:[0,3,4],conveni:0,convent:0,coordin:[3,4,5],core:[4,5],correct:[0,4],correctli:0,correspond:4,cost:[4,5],could:[0,3,4,5],count:4,counter:0,cover:5,cpu:0,creat:[0,1,3,4],create_kei:3,create_receipt:[0,3],creation:4,creator:4,critic:4,cryptograph:5,cryptographi:[1,4,5],ctrl:0,cull:3,current:[0,2,3,4],current_download:0,current_filenam:0,curv:[3,4,5],curve25519:[3,4,5],custom:4,d:4,daemon:3,dai:4,data:[0,3,4,5],date:0,debian:4,debug:3,decai:4,decid:[3,4],decod:0,decrypt:[3,4],dedic:4,def:0,default_timeout:3,defin:[0,4],definit:4,delai:4,deliv:[0,3],deliveri:[0,3,5],demand:3,demonstr:0,depend:1,deploi:4,deregist:3,deregister_announce_handl:3,deriv:[4,5],describ:[3,4],descript:0,design:[4,5],desir:[0,4],destin:[0,1,2],destination_1:0,destination_2:0,destination_clos:0,destination_hash:[0,3],destination_hexhash:0,detail:[0,2,3],detect:0,determin:[3,4],develop:[2,4],devic:[2,3,4],dh:3,did:0,differ:[0,1,3,4,5],diffi:[4,5],digit:[4,5],dir:0,direct:[0,3,4],directli:[3,4,5],directori:0,disable_encrypt:3,disappear:3,discard:4,disconnect:0,discoveri:4,discuss:4,disk:[0,3],displai:4,distanc:4,distinct:4,distribut:[0,3,4],divmod:0,document:4,doe:[0,2,3,4],don:[0,1],done:[0,4],dot:4,down:0,downgrad:3,download:0,download_began:0,download_conclud:0,download_finish:0,download_start:0,download_tim:0,driver:5,drop:4,duplex:[4,5],e:0,each:[0,4],earlier:4,eas:4,easi:[4,5],easiest:[1,4],easili:[4,5],ecdh:[4,5],echo:[1,2],echo_destin:0,echo_request:0,ed25519:[4,5],effici:[0,4,5],ei:0,either:4,elif:0,ellipt:[3,4,5],els:[0,4],emploi:4,emptor:2,enabl:3,enable_transport:4,encapsul:5,encod:0,encrypt:[0,1,3,4,5],encrypted_mdu:3,encryptionless:3,end:[0,3,4,5],endpoint:[0,3,4],engin:4,ensur:4,enter:0,entir:4,entiti:4,entri:[0,4],enumer:0,environ:4,environment:4,environmentlogg:4,ephemer:[3,4,5],equal:4,equip:4,equl:[],error:[0,3],essenti:4,establish:[0,3,5],ethernet:[4,5],even:[4,5],everi:[0,3,4],everyon:4,everyth:[0,4],exact:4,exactli:[3,4],exampl:[1,2,3,4,5],example_util:0,exampleannouncehandl:0,exce:0,except:[0,4],exchang:[3,4,5],execut:[0,3],exhaust:4,exist:[0,4,5],exit:[0,1,3],exit_handl:0,expand:4,expect:[0,4],experi:[1,4],experiment:5,explain:3,explan:4,explicit:3,explicitli:3,explor:[0,4,5],expos:3,extend:[0,4],extern:[3,5],extrem:5,fa7ddfab5213f916dea:4,face:1,fact:[4,5],fail:[0,3],fals:[0,3],far:4,fast:2,featur:[4,5],feed:3,feedback:0,fernet:5,few:[4,5],field:4,file:[0,1,3,4,5],file_resourc:0,file_s:0,filelist:0,filelist_data:0,filelist_receiv:0,filelist_timeout_job:0,filenam:0,filetransf:[1,2,3],filter:[0,4],find:4,firmwar:4,first:[0,3,4],fit:0,five:0,fix:4,flag:[3,4],flush:0,folder:1,follow:[0,4,5],forcibl:3,foremost:5,form:[3,4],format:[0,2,5],forth:0,forward:[3,4,5],found:[0,1,4],free:5,frequenc:4,from:[0,1,3,4,5],from_byt:3,from_fil:3,fromhex:0,fruit:0,full:[3,4],full_hash:3,full_nam:3,fulli:[4,5],fundament:4,further:[1,2],futur:[3,4],g:0,ga:0,gatekeep:4,gener:[0,3,4,5],generalis:5,get:[0,2,3,5],get_private_kei:3,get_public_kei:3,get_random_hash:[0,3],get_rtt:[0,3],get_statu:3,gi:0,gigabyt:5,git:1,github:[0,1],give:4,given:4,global:[0,5],go:[0,1,4],goal:2,good:4,got:0,govern:4,grape:0,great:4,greater:4,group:[3,4],guarante:4,guid:[1,3,4],h:[1,4],ha:[0,3,4,5],had:4,half:[4,5],hand:0,handheld:4,handl:[0,3,4,5],handler:[0,3],happen:0,hardwar:[3,4,5],has_path:[0,3],hasattr:0,hash:[0,1,3,4],hash_from_name_and_ident:3,hashmap:0,have:[0,1,3,4],hazard:3,header:4,header_1:4,header_2:4,header_typ:3,hear:4,heard:[3,4],helium:0,hellman:[4,5],help:[0,4,5],here:[0,4],hexadecim:[0,4],high:[4,5],higher:[4,5],highli:4,hint:0,hit:0,hmac:5,hoc:5,hold:[3,4],hop:[4,5],host:[0,4,5],hour:0,how:[0,4,5],howev:4,http:[0,1],human:[0,3],i:0,id:4,idea:4,ident:[0,2],identif:5,identifi:4,identify:4,ie:[],ignor:[3,4],immedi:1,impact:4,implement:[0,4,5],implicit:[3,4],inactive_for:3,inbound:3,includ:[0,3,4],incom:[0,3],incompat:[3,4],indefinit:4,independ:3,independt:5,index:[0,2],indirectli:4,individu:4,inevit:4,infer:4,info:[3,4],inform:[0,1,2,3,4],infrastructur:4,ingo:3,initi:4,initialis:[0,3],input:0,insert:4,instal:1,instanc:[0,3],instanti:3,instead:[0,4],integr:4,intend:4,intention:4,inter:3,interact:[0,4],interest:4,interfac:[0,2,3,4],intern:[3,4],internet:[4,5],interv:3,introduc:4,introduct:2,intuit:5,invalid:[0,3],investig:4,ip:[4,5],isdir:0,isfil:0,ism:4,its:[3,4],itself:[2,3,4],iv:5,job:0,join:[0,4],just:[0,4,5],k:0,kbp:4,keep:[0,3,4,5],keepal:[3,4],kei:[0,2,3,5],kept:[3,4],kernel:5,keyboardinterrupt:0,keyerror:3,keypair:4,keysiz:3,ki:0,kill:3,kilomet:4,kind:4,know:[0,3,4],knowledg:4,known:[0,3,4],krypton:0,lack:4,laid:4,larg:[0,4],larger:4,last:[0,3],last_unit:0,latenc:[4,5],later:0,latest:[0,1],latest_client_link:0,launch:1,lavg:4,layer:[4,5],lead:4,learn:[0,4],least:[4,5],leav:4,ledger:4,left:4,len:0,length:[0,3],less:[4,5],let:[0,4],level:4,librari:1,licens:4,light:4,like:[1,3,4],limit:4,line:[0,1,4,5],link:[2,5],link_clos:0,link_establish:0,linkexampl:0,linux:4,list:[0,3,4],list_deliv:0,list_fil:0,list_packet:0,list_receipt:0,list_timeout:0,listdir:0,listen:[0,4],littl:4,lki:4,lkr:4,ll:[0,1,5],ln:1,load:[0,3],load_private_kei:3,load_public_kei:3,local:[0,3,4,5],locat:4,log:0,log_error:0,log_info:0,loglevel:0,longer:[0,4],look:[1,4],loop:0,lora:[4,5],lorawan:4,lot:4,low:[4,5],lxmf:1,m:[0,4],mac:4,machin:4,made:4,mai:4,main:0,maintain:4,make:[1,4],malici:4,manag:3,mani:[0,4,5],manipul:4,manual:[0,1,3],mark:4,markqvist:[0,1],master:[0,3],match:0,maximum:[3,4],mcu:4,mdu:0,mean:4,measur:4,mechan:2,medium:[4,5],memori:4,mention:4,menu:0,menu_mod:0,mesh:5,messag:[0,1,3,4],messeng:4,metavar:0,method:[0,3,4],methodolog:4,mhz:4,mi:0,microcontrol:4,microwav:4,might:4,millisecond:0,mind:5,minim:[2,4],minimalsampl:0,minimum:[0,4],minut:[0,4],mode:[0,1,4,5],modem:[3,4,5],modul:[0,4,5],moment:[4,5],monitor:4,more:[3,4,5],most:[1,4,5],motiv:2,move:1,mtu:[4,5],much:4,multi:[4,5],multilater:4,multipl:[0,4],multipoint:4,must:[0,3,4],my:4,n:0,name:[0,3],namespac:0,nano:1,narg:0,necessari:[1,3,4],necessarili:4,need:[0,2,4,5],neglig:4,neither:4,neon:0,network:[0,1,3,4,5],never:3,newer:4,newest:4,newli:4,next:[1,4],nicknam:4,no_inbound_for:3,no_outbound_for:3,nobl:0,noble_ga:0,noble_gas:0,node:[2,5],nomad:1,non:[3,4],none:[0,3,4],normal:0,notat:4,note:[0,4],noth:5,notic:4,notif:[0,3],now:[0,1,4],nt:0,num:0,number:[0,3,4],object:3,obtain:4,occur:5,off:[4,5],offer:[2,3,4],often:4,oganesson:0,old:4,onc:[4,5],one:[0,3,4,5],onli:[0,3,4,5],onlin:4,open:[0,3,4,5],openmodem:5,oper:[3,4,5],opt:4,optic:5,option:[0,1],orient:4,origin:4,original_hash:3,os:[0,4,5],ospf:4,other:[3,4],otherwis:[3,4],our:[0,4],out:[0,3,4,5],outbound:3,outgo:[0,3,4],outlin:[1,4],outward:4,over:[0,3,4,5],overal:4,overcom:4,overhead:4,overrid:0,overview:4,own:[0,1,3,4],owner:3,p:[0,4],pack:0,packb:0,packet:[0,2,5],packet_callback:0,packet_deliv:0,packet_receipt:[0,3],packet_timed_out:0,packet_typ:3,packetreceipt:[0,3],pad:5,page:[2,4],pair:4,palm:0,paramet:3,pars:0,parse_arg:0,parser:0,part:[0,4],particip:[2,4],pass:[0,3,4],path:[0,1,3,4],path_respons:3,pathfind:[],pattern:4,payload:[3,4],peach:0,peer:[3,4],peer_pub_byt:3,peer_sig_pub_byt:3,peopl:4,per:[4,5],percent:0,perfect:4,perform:4,period:4,persecut:4,person:4,philosophi:4,physic:4,pi:[0,4,5],piec:4,ping:1,pip3:1,pip:1,pkcs7:5,place:4,plain:[0,3,4],plain_mdu:3,plaintext:[0,3],platform:4,pleas:[0,5],plenti:4,plu:4,pmr:4,point:4,pomelo:0,port:[4,5],possess:4,possibl:[4,5],potenti:[0,4],practic:[4,5],pre:[3,4],predict:4,prefer:4,prepar:0,presenc:3,press:0,pretend:4,pretti:4,prettyhexrep:0,previou:0,previous:[3,4],primari:4,principl:[4,5],print:0,print_filelist:0,print_help:0,print_menu:0,prioriti:4,prioritis:2,privaci:5,privat:[3,4,5],probabl:[0,4,5],procedur:4,process:[1,3,4],product:3,program:[0,2,3,4],program_setup:0,programm:4,programmat:4,progress:[0,3,5],progress_callback:3,project:1,prompt:0,proof:[0,3,4],proof_requested_callback:3,proof_strategi:3,propag:4,protocol:[1,2,5],prove:[0,4],prove_al:[0,3],prove_app:3,prove_non:3,proven:[3,4],provid:[0,1,2,3,4,5],prv_byte:3,pub_byt:3,public_inform:0,purchas:[4,5],purg:3,purpos:[3,4],purposefulli:4,put:0,py:[0,1],pyseri:1,python3:1,python:[4,5],q:0,queri:0,queue:4,quinc:0,quit:0,r:[0,4],radio:[3,4,5],radiu:4,radon:0,rais:[0,3],rand:4,randint:0,random:[0,3,4],randomli:[0,4],rang:[0,4,5],raspberri:[4,5],rate:0,rb:0,re:[0,3,4],reach:2,reachabl:[0,3,4],read:[0,1,4],readabl:[0,3,4],readi:[0,1],readili:5,real:5,reason:4,reassembl:4,recal:[0,3],recall_app_data:3,recap:4,receipt:[0,2,4],receiv:[0,3,4],received_announc:[0,3],recip:1,recipi:4,recommend:[0,4],reconstruct:4,record:4,recreat:4,refer:[0,1,2],regard:4,regist:[0,3],register_announce_handl:[0,3],rel:[4,5],releas:[1,4],relev:[0,3],reli:4,reliabl:[4,5],rem:0,remain:4,rememb:4,remot:[0,5],remotesensor:4,repeat:1,replac:[1,4],repli:0,replic:4,reply_data:0,reply_text:0,repositori:1,repres:4,represent:[0,4],request:[0,3,4],request_destin:0,request_packet:0,request_path:[0,3],requir:[0,4,5],research:5,resend:3,reserv:4,resili:5,resourc:[0,2],resource_callback:3,resource_sending_conclud:0,resource_strategi:3,respond:[0,3],rest:5,result:[0,4],reticulum:0,retransmiss:4,retransmit:4,retri:4,reveal:4,review:5,right:[],rn:[0,1,3],rnode:[4,5],robot:4,rotat:4,round:[0,3],rout:[3,4,5],rprogress:0,rsa:[],rtt:[0,4],rttstring:0,rule:4,run:[0,1,3,4,5],runtim:4,rw:4,s:[0,1,4,5],said:4,same:[1,3,4],satisfi:4,save:[3,4],save_error:0,saved_filenam:0,scenario:[1,4],screen:0,search:2,second:[0,3,4,5],secreci:[3,4,5],section:4,secur:[4,5],see:[0,3,4],seen:4,segment_index:3,select:0,self:[0,5],send:[0,3,4],sender:[0,4],sensibl:1,sensor:4,sent:[0,3,4],sentiment:4,separ:4,sequenc:[0,3,4,5],serial:[4,5],serv:[0,4],serve_path:0,server:[0,1],server_callback:0,server_destin:0,server_fil:0,server_ident:0,server_link:0,server_loop:0,server_packet_receiv:0,session:4,set:[0,3,4,5],set_default_app_data:3,set_delivery_callback:[0,3],set_link_closed_callback:0,set_link_established_callback:[0,3],set_packet_callback:[0,3],set_proof_requested_callback:3,set_proof_strategi:[0,3],set_resource_callback:3,set_resource_concluded_callback:[0,3],set_resource_started_callback:[0,3],set_resource_strategi:[0,3],set_timeout:[0,3],set_timeout_callback:3,setdaemon:0,setup:[0,2],sever:3,sha256:5,sha:[3,4],shall:4,share:[1,3,4],shelf:[4,5],shortest:4,should:[0,3,4,5],should_allow_unencrypt:3,should_quit:0,should_use_implicit_proof:3,shown:0,side:5,sign:[3,4],signatur:[3,4,5],similar:5,simpl:[0,4,5],simplest:4,simpli:[0,1,4],simplic:4,sinc:[0,3,4],singl:[0,3,4],singular:4,situat:4,size:[0,3,4],size_str:0,sleep:0,slice:0,slow:[0,4],small:[0,4],so:[0,1,4,5],softwar:[4,5],some:[0,1,4],someth:4,somethign:0,soon:3,sort:4,sourc:[0,1,4,5],space:[0,5],span:4,special:4,specif:[0,2,3,5],specifi:[0,3],spectrum:4,split:0,sponsor:5,stabl:[4,5],stack:[0,1,4,5],stage:4,standard:4,start:[0,2,3,4],startup:0,state:0,station:4,statist:0,statu:[0,2,3,4],stdout:0,step:1,still:[0,4],stop:5,store:[0,4],store_tru:0,str:0,strategi:3,stream:4,strength:5,strictli:4,string:[0,3],structur:4,subject:4,subsequ:4,successful:3,successfulli:0,sucessfulli:4,suffic:4,suffici:4,suffix:0,suit:[1,4],suitabl:[0,4],suppli:[3,4],support:[0,2,4],sy:0,symlink:1,symmetr:[3,4],system:[0,2,3,5],t:[0,1,4],tabl:4,take:[0,1,4,5],taken:[0,4],tangerin:0,target:0,tcp:[4,5],tdata:0,teardown:[0,3],teardown_reason:0,teffect:0,tell:0,temperatur:4,ten:4,term:4,termin:3,terminolog:4,test:4,text:[0,4],tfile:0,than:[0,4],thei:[0,3,4],them:[0,4],thereaft:4,therefor:[4,5],thi:[0,1,2,3,4],though:4,thourough:5,thread:0,three:4,through:[4,5],throughout:4,throughput:[4,5],thu:4,ti:[0,4],time:[0,1,3,4],timeout:[0,3],timeout_callback:0,timeoutarg:0,timestr:0,tnc:[3,5],to_fil:3,todai:4,todo:[],togeth:4,token:[3,4],too:[0,4],tool:5,top:4,topic:4,topolog:4,total:[4,5],total_s:0,touch:5,toward:[0,4],traffic:[0,3,4],tramsit:[],transceiv:[4,5],transfer:[0,3,4,5],transfer_s:0,transmiss:4,transmit:[0,4],transpar:4,transport:[0,2,5],transport_en:3,transport_id:3,transport_typ:3,travers:4,treat:4,tri:0,trip:[0,3],trivial:5,truli:4,truncat:[3,4],truncated_hash:3,truncated_hashlength:3,trust:4,trustless:[4,5],ttime:0,ttransfer:0,tunnel:[4,5],tupl:3,two:[0,4],type:[0,2,3],typeerror:3,udp:[4,5],umsgpack:0,uncencrypt:0,underli:5,understand:[1,2],unencrypt:[0,3,4],unequivoc:4,unforg:5,uninterest:0,uniqu:[4,5],unit:0,unknown:[0,3,4],unless:[1,3,4],unlicens:4,unpack:0,unpackb:0,unsupport:3,until:[0,3,4],unwant:4,up:[0,4,5],updat:[0,3],upon:[0,4],urandom:5,us:[0,2,3,4],usabl:4,usag:[],usb:[4,5],useabl:4,user:[0,1,3,4],user_input:0,userland:5,utf:0,util:[0,1,4],utilis:[4,5],valid:[0,3,4],valu:4,valueerror:[0,3],variabl:0,varieti:[4,5],variou:[0,4],ve:1,vendor:0,veri:[3,4,5],verif:[3,4],verifi:[0,4],versa:5,version:3,vhf:4,via:[1,4],vice:5,view:4,visibl:0,wa:[0,3,4,5],wai:[0,1,4],wait:[0,4],want:[0,1,4,5],warrant:5,wb:0,we:[0,4],well:[3,4,5],went:0,what:[0,1,2,3,4],whatev:4,when:[0,1,3,4],whenev:3,where:[2,3,4],whereupon:4,whether:[0,3,4],which:[0,1,3,4],who:4,wide:[4,5],wifi:[4,5],wildcard:0,window:4,wire:[4,5],wish:4,within:[0,3,4],won:0,work:[4,5],world:5,would:4,write:[0,3],written:4,wrong:0,x25519:[3,4,5],x:4,xenon:0,y:0,ye:4,year:4,yet:[0,4],yi:0,you:[0,1,2,3,4,5],your:[0,1,4,5],yourself:[4,5],z:0,zero:3,zi:0},titles:["Examples","Getting Started Fast","Reticulum Network Stack Manual","API Reference","Understanding Reticulum","What is Reticulum?"],titleterms:{"1":[],"2":[],"class":3,"function":4,"public":4,"try":1,The:4,announc:[0,4],api:3,base:1,basic:4,binari:4,broadcast:0,can:5,caveat:5,current:5,deliveri:[],destin:[3,4],detail:4,develop:1,devic:5,doe:5,echo:0,emptor:5,establish:4,exampl:0,fast:1,filetransf:0,format:4,further:4,get:[1,4],goal:4,ident:[3,4],indic:2,interfac:5,introduct:4,kei:4,link:[0,3,4],manual:2,mechan:4,minim:0,motiv:4,name:4,network:2,node:4,offer:5,packet:[3,4],particip:1,pathfind:[],prioritis:4,program:1,protocol:4,proven:[],reach:4,receipt:3,refer:[3,4],resourc:[3,4],reticulum:[1,2,3,4,5],setup:4,specif:4,stack:2,start:1,statu:5,step:[],support:5,system:4,tabl:2,transport:[3,4],type:[4,5],understand:4,us:[1,5],what:5,where:5}}) \ No newline at end of file +Search.setIndex({docnames:["examples","gettingstartedfast","index","reference","understanding","whatis"],envversion:{"sphinx.domains.c":2,"sphinx.domains.changeset":1,"sphinx.domains.citation":1,"sphinx.domains.cpp":3,"sphinx.domains.index":1,"sphinx.domains.javascript":2,"sphinx.domains.math":2,"sphinx.domains.python":3,"sphinx.domains.rst":2,"sphinx.domains.std":2,sphinx:56},filenames:["examples.rst","gettingstartedfast.rst","index.rst","reference.rst","understanding.rst","whatis.rst"],objects:{"RNS.Destination":{announce:[3,1,1,""],app_and_aspects_from_name:[3,1,1,""],clear_default_app_data:[3,1,1,""],create_keys:[3,1,1,""],decrypt:[3,1,1,""],encrypt:[3,1,1,""],full_name:[3,1,1,""],get_private_key:[3,1,1,""],hash:[3,1,1,""],hash_from_name_and_identity:[3,1,1,""],load_private_key:[3,1,1,""],set_default_app_data:[3,1,1,""],set_link_established_callback:[3,1,1,""],set_packet_callback:[3,1,1,""],set_proof_requested_callback:[3,1,1,""],set_proof_strategy:[3,1,1,""],sign:[3,1,1,""]},"RNS.Identity":{CURVE:[3,2,1,""],KEYSIZE:[3,2,1,""],TRUNCATED_HASHLENGTH:[3,2,1,""],decrypt:[3,1,1,""],encrypt:[3,1,1,""],from_bytes:[3,1,1,""],from_file:[3,1,1,""],full_hash:[3,1,1,""],get_private_key:[3,1,1,""],get_public_key:[3,1,1,""],get_random_hash:[3,1,1,""],load_private_key:[3,1,1,""],load_public_key:[3,1,1,""],recall:[3,1,1,""],recall_app_data:[3,1,1,""],sign:[3,1,1,""],to_file:[3,1,1,""],truncated_hash:[3,1,1,""],validate:[3,1,1,""]},"RNS.Link":{CURVE:[3,2,1,""],DEFAULT_TIMEOUT:[3,2,1,""],KEEPALIVE:[3,2,1,""],disable_encryption:[3,1,1,""],inactive_for:[3,1,1,""],no_inbound_for:[3,1,1,""],no_outbound_for:[3,1,1,""],set_packet_callback:[3,1,1,""],set_resource_callback:[3,1,1,""],set_resource_concluded_callback:[3,1,1,""],set_resource_started_callback:[3,1,1,""],set_resource_strategy:[3,1,1,""],teardown:[3,1,1,""]},"RNS.Packet":{ENCRYPTED_MDU:[3,2,1,""],PLAIN_MDU:[3,2,1,""],resend:[3,1,1,""],send:[3,1,1,""]},"RNS.PacketReceipt":{get_rtt:[3,1,1,""],get_status:[3,1,1,""],set_delivery_callback:[3,1,1,""],set_timeout:[3,1,1,""],set_timeout_callback:[3,1,1,""]},"RNS.Resource":{advertise:[3,1,1,""],cancel:[3,1,1,""],progress:[3,1,1,""]},"RNS.Reticulum":{should_allow_unencrypted:[3,1,1,""],should_use_implicit_proof:[3,1,1,""],transport_enabled:[3,1,1,""]},"RNS.Transport":{deregister_announce_handler:[3,1,1,""],has_path:[3,1,1,""],register_announce_handler:[3,1,1,""],request_path:[3,1,1,""]},RNS:{Destination:[3,0,1,""],Identity:[3,0,1,""],Link:[3,0,1,""],Packet:[3,0,1,""],PacketReceipt:[3,0,1,""],Resource:[3,0,1,""],Reticulum:[3,0,1,""],Transport:[3,0,1,""]}},objnames:{"0":["py","class","Python class"],"1":["py","method","Python method"],"2":["py","attribute","Python attribute"]},objtypes:{"0":"py:class","1":"py:method","2":"py:attribute"},terms:{"0":[0,3,4,5],"00":4,"000":[4,5],"00000000":4,"00000100":4,"00000111":4,"01":4,"01010000":4,"05":0,"1":[0,3,4,5],"10":[0,4],"100":[0,4],"1000":[0,4],"1024":0,"11":4,"1200":4,"128":[4,5],"14":4,"141":[],"15":[3,4],"151":4,"18":4,"180":4,"182":[],"2":[0,4],"20":[0,4],"205":[],"240":[4,5],"25":[0,5],"256":[3,4],"270":4,"2f":0,"3":[0,4,5],"323":[],"33":4,"34":4,"360":3,"3600":0,"383":3,"3e12fc71692f8ec47bc5":1,"4":4,"409":[],"430":4,"45":0,"477":[3,4],"5":[0,4],"500":[4,5],"512":3,"60":0,"62":[4,5],"7":4,"77":4,"8":0,"80":[3,4],"80e29bf7cccaf31431b3":4,"86":4,"868":4,"900":4,"95":4,"abstract":4,"break":[4,5],"byte":[0,3,4,5],"case":[1,4],"class":[0,2,5],"default":[0,3,4],"do":[0,1,4,5],"float":[0,3],"function":[0,2,3,5],"import":[0,1,4],"int":0,"long":[0,4],"new":[0,3,4],"public":[0,2,3],"return":[0,3],"short":4,"static":3,"throw":3,"true":[0,3],"try":[0,2],"while":[0,3,4,5],A:[0,3,4,5],And:0,As:[3,4,5],At:4,Be:3,But:4,By:[0,4],For:[3,4],IN:[0,3],If:[0,1,3,4,5],In:[0,1,4,5],It:[0,3,4,5],No:[4,5],One:3,Or:4,That:4,The:[0,1,2,3,5],There:[4,5],These:4,To:[0,4,5],Will:3,With:4,_:4,__:4,______:4,_______:4,________:4,________________:4,__init__:0,__main__:0,__name__:0,_exit:0,ab:0,abl:[0,3,4],about:[0,3,4],abov:[1,4],accept:[3,4],accept_al:[0,3],accept_app:3,accept_non:3,access:[3,4],accord:4,accordingli:0,acheiv:4,achiev:[3,4],acknowledg:5,act:[3,4],action:0,activ:[0,3,4],actor:4,actual:[0,1,4],ad:[0,3,4,5],add:0,add_argu:0,addit:[4,5],addr1:4,addr2:4,address:[0,3,4,5],adress:[0,3,5],advantag:3,advertis:[0,3],advis:4,ae:[4,5],after:[0,4],again:[1,4],against:4,agent:4,agnost:4,agnostic:4,aim:[2,4],aliv:[3,4],all:[0,2,3,4,5],allow:[0,3,4,5],almost:4,along:[3,4],alreadi:[0,4],also:[0,3,4,5],alter:4,altern:0,although:5,alwai:[3,4],amateur:5,amount:[3,4,5],an:[0,1,3,4,5],ani:[0,1,3,4,5],announc:[2,3],announce_handl:0,announced_ident:[0,3],announceloop:0,announcesampl:0,anonym:4,anoth:[1,3,4],answer:4,anyon:[0,3,4],anyth:4,anywher:0,apart:4,api:[1,2,4,5],app:[0,3,4],app_and_aspects_from_nam:3,app_data:[0,3],app_nam:[0,3],app_timeout:0,append:[0,4],appli:4,applic:[0,3,4],approv:4,approxim:4,ar:[0,3,4,5],arbitrari:[3,4],arbritrari:5,area:5,arg:0,argon:0,argpars:0,argument:[0,3],argumentpars:0,around:4,arriv:[0,4],ask:[0,3],aspect:[0,3,4],aspect_filt:[0,3],assign:4,associ:[1,3,4],assum:4,asymmetr:5,attached_interfac:3,attribut:3,audit:5,authent:[4,5],author:4,auto:[3,4],auto_compress:3,autoconfigur:5,autom:4,automat:[0,3,4,5],autonom:4,autoomat:0,avail:[0,4,5],averag:4,avoid:4,awai:4,awar:4,ax:5,b:0,back:[0,4,5],band:4,bandwidth:[4,5],bare:0,barrier:4,base:[2,4,5],basi:[3,4,5],basic:[0,1,2],baud:4,becaus:4,becom:0,been:[0,3,4,5],befor:[0,3,4],begin:[0,3],begun:3,behind:4,being:4,belief:4,below:1,best:[1,4,5],beta:5,between:[0,3,4],bgp:4,bi:4,bidirect:4,binari:[0,2],bit:[3,4,5],blob:[0,4],both:[3,4,5],bp:4,briefli:4,broadcast:[2,3,4],broadcast_destin:0,broadcastloop:0,bug:5,build:[0,4,5],built:[1,4,5],bundl:0,c:[0,4],cad:4,calcul:4,call:[0,3,4,5],callabl:3,callback:[0,3],can:[0,1,2,3,4],cancel:3,cannot:0,capac:4,carambola:0,care:[3,4,5],carri:[3,4],carrier:5,caveat:2,cb:4,cbc:5,cd:1,censor:4,censorship:4,central:4,certain:[0,4],challeng:4,chang:[0,1,4,5],channel:[0,4,5],channelarg:0,chapter:[1,4],charact:0,characterist:4,cheap:4,check:0,checksum:[3,5],choos:0,chose:4,chunk:0,ciphertext:3,ciphertext_token:3,cl:0,clear:[0,3,4],clear_default_app_data:3,clear_screen:0,client:[0,1,3],client_connect:0,client_disconnect:0,client_loop:0,client_packet_receiv:0,client_request:0,clone:1,close:[0,3],closer:4,cluster:4,code:[0,4],com:[0,1],combin:4,come:4,command:[0,1],common:4,commun:[0,1,3,4,5],compat:4,complet:[0,1,3,4,5],compon:4,compos:4,compress:[0,3,4],comput:[1,4],concaten:3,concept:4,conclud:[0,3],concurr:4,condit:4,config:[0,1],configarg:0,configdir:3,configpath:0,configur:[0,3,4,5],confirm:[4,5],connect:[0,3,4,5],consequ:4,consid:[4,5],consist:4,constant:[3,4],construct:4,contact:4,contain:[0,3,4],content:[],context:[3,4],control:[0,3,4],conveni:0,convent:0,coordin:[3,4,5],core:[4,5],correct:[0,4],correctli:0,correspond:4,cost:[4,5],could:[0,3,4,5],count:4,counter:0,cover:5,cpu:0,creat:[0,1,3,4],create_kei:3,create_receipt:[0,3],creation:4,creator:4,critic:4,cryptograph:5,cryptographi:[1,4,5],ctrl:0,cull:3,current:[0,2,3,4],current_download:0,current_filenam:0,curv:[3,4,5],curve25519:[3,4,5],custom:4,d:4,daemon:3,dai:4,data:[0,3,4,5],date:0,debian:4,debug:3,decai:4,decid:[3,4],decod:0,decrypt:[3,4],dedic:4,def:0,default_timeout:3,defin:[0,4],definit:4,delai:4,deliv:[0,3],deliveri:[0,3,5],demand:3,demonstr:0,depend:1,deploi:4,deregist:3,deregister_announce_handl:3,deriv:[4,5],describ:[3,4],descript:0,design:[4,5],desir:[0,4],destin:[0,1,2],destination_1:0,destination_2:0,destination_clos:0,destination_hash:[0,3],destination_hexhash:0,detail:[0,2,3],detect:0,determin:[3,4],develop:[2,4],devic:[2,3,4],dh:3,did:0,differ:[0,1,3,4,5],diffi:[4,5],digit:[4,5],dir:0,direct:[0,3,4],directli:[3,4,5],directori:0,disable_encrypt:3,disappear:3,discard:4,disconnect:0,discoveri:4,discuss:4,disk:[0,3],displai:4,distanc:4,distinct:4,distribut:[0,3,4],divmod:0,document:4,doe:[0,2,3,4],don:[0,1],done:[0,4],dot:4,down:0,downgrad:3,download:0,download_began:0,download_conclud:0,download_finish:0,download_start:0,download_tim:0,driver:5,drop:4,duplex:[4,5],e:0,each:[0,4],earlier:4,eas:4,easi:[4,5],easiest:[1,4],easili:[4,5],ecdh:[4,5],echo:[1,2],echo_destin:0,echo_request:0,ed25519:[4,5],effici:[0,4,5],ei:0,either:4,elif:0,ellipt:[3,4,5],els:[0,4],emploi:4,emptor:2,enabl:3,enable_transport:4,encapsul:5,encod:0,encrypt:[0,1,3,4,5],encrypted_mdu:3,encryptionless:3,end:[0,3,4,5],endpoint:[0,3,4],engin:4,ensur:4,enter:0,entir:4,entiti:4,entri:[0,4],enumer:0,environ:4,environment:4,environmentlogg:4,ephemer:[3,4,5],equal:4,equip:4,equl:[],error:[0,3],essenti:4,establish:[0,3,5],ethernet:[4,5],even:[4,5],everi:[0,3,4],everyon:4,everyth:[0,4],exact:4,exactli:[3,4],exampl:[1,2,3,4,5],example_util:0,exampleannouncehandl:0,exce:0,except:[0,4],exchang:[3,4,5],execut:[0,3],exhaust:4,exist:[0,4,5],exit:[0,1,3],exit_handl:0,expand:4,expect:[0,4],experi:[1,4],experiment:5,explain:3,explan:4,explicit:3,explicitli:3,explor:[0,4,5],expos:3,extend:[0,4],extern:[3,5],extrem:5,fa7ddfab5213f916dea:4,face:1,fact:[4,5],fail:[0,3],fals:[0,3],far:4,fast:2,featur:[4,5],feed:3,feedback:0,fernet:5,few:[4,5],field:4,file:[0,1,3,4,5],file_resourc:0,file_s:0,filelist:0,filelist_data:0,filelist_receiv:0,filelist_timeout_job:0,filenam:0,filetransf:[1,2,3],filter:[0,4],find:4,firmwar:4,first:[0,3,4],fit:0,five:0,fix:4,flag:[3,4],flush:0,folder:1,follow:[0,4,5],forcibl:3,foremost:5,form:[3,4],format:[0,2,5],forth:0,forward:[3,4,5],found:[0,1,4],free:5,frequenc:4,from:[0,1,3,4,5],from_byt:3,from_fil:3,fromhex:0,fruit:0,full:[3,4],full_hash:3,full_nam:3,fulli:[4,5],fundament:4,further:[1,2],futur:[3,4],g:0,ga:0,gatekeep:4,gener:[0,3,4,5],generalis:5,get:[0,2,3,5],get_private_kei:3,get_public_kei:3,get_random_hash:[0,3],get_rtt:[0,3],get_statu:3,gi:0,gigabyt:5,git:1,github:[0,1],give:4,given:4,global:[0,5],go:[0,1,4],goal:2,good:4,got:0,govern:4,grape:0,great:4,greater:4,group:[3,4],guarante:4,guid:[1,3,4],h:[1,4],ha:[0,3,4,5],had:4,half:[4,5],hand:0,handheld:4,handl:[0,3,4,5],handler:[0,3],happen:0,hardwar:[3,4,5],has_path:[0,3],hasattr:0,hash:[0,1,3,4],hash_from_name_and_ident:3,hashmap:0,have:[0,1,3,4],hazard:3,header:4,header_1:4,header_2:4,header_typ:3,hear:4,heard:[3,4],helium:0,hellman:[4,5],help:[0,4,5],here:[0,4],hexadecim:[0,4],high:[4,5],higher:[4,5],highli:4,hint:0,hit:0,hmac:5,hoc:5,hold:[3,4],hop:[4,5],host:[0,4,5],hour:0,how:[0,4,5],howev:4,http:[0,1],human:[0,3],i:0,id:4,idea:4,ident:[0,2],identif:5,identifi:4,identify:4,ie:[],ignor:[3,4],immedi:1,impact:4,implement:[0,4,5],implicit:[3,4],inactive_for:3,inbound:3,includ:[0,3,4],incom:[0,3],incompat:[3,4],indefinit:4,independ:3,independt:5,index:[0,2],indirectli:4,individu:4,inevit:4,infer:4,info:[3,4],inform:[0,1,2,3,4],infrastructur:4,ingo:3,initi:4,initialis:[0,3],input:0,insert:4,instal:1,instanc:[0,3],instanti:3,instead:[0,4],integr:4,intend:4,intention:4,inter:3,interact:[0,4],interest:4,interfac:[0,2,3,4],intern:[3,4],internet:[4,5],interv:3,introduc:4,introduct:2,intuit:5,invalid:[0,3],investig:4,ip:[4,5],isdir:0,isfil:0,ism:4,its:[3,4],itself:[2,3,4],iv:5,job:0,join:[0,4],just:[0,4,5],k:0,kbp:4,keep:[0,3,4,5],keepal:[3,4],kei:[0,2,3,5],kept:[3,4],kernel:5,keyboardinterrupt:0,keyerror:3,keypair:4,keysiz:3,ki:0,kill:3,kilomet:4,kind:4,know:[0,3,4],knowledg:4,known:[0,3,4],krypton:0,lack:4,laid:4,larg:[0,4],larger:4,last:[0,3],last_unit:0,latenc:[4,5],later:0,latest:[0,1],latest_client_link:0,launch:1,lavg:4,layer:[4,5],lead:4,learn:[0,4],least:[4,5],leav:4,ledger:4,left:4,len:0,length:[0,3],less:[4,5],let:[0,4],level:4,librari:1,licens:4,light:4,like:[1,3,4],limit:4,line:[0,1,4,5],link:[2,5],link_clos:0,link_establish:0,linkexampl:0,linux:4,list:[0,3,4],list_deliv:0,list_fil:0,list_packet:0,list_receipt:0,list_timeout:0,listdir:0,listen:[0,4],littl:4,lki:4,lkr:4,ll:[0,1,5],ln:1,load:[0,3],load_private_kei:3,load_public_kei:3,local:[0,3,4,5],locat:4,log:0,log_error:0,log_info:0,loglevel:0,longer:[0,4],look:[1,4],loop:0,lora:[4,5],lorawan:4,lot:4,low:[4,5],lxmf:1,m:[0,4],mac:4,machin:4,made:4,mai:4,main:0,maintain:4,make:[1,4],malici:4,manag:3,mani:[0,4,5],manipul:4,manual:[0,1,3],mark:4,markqvist:[0,1],master:[0,3],match:0,maximum:[3,4],mcu:4,mdu:0,mean:4,measur:4,mechan:2,medium:[4,5],memori:4,mention:4,menu:0,menu_mod:0,mesh:5,messag:[0,1,3,4],messeng:4,metavar:0,method:[0,3,4],methodolog:4,mhz:4,mi:0,microcontrol:4,microwav:4,might:4,millisecond:0,mind:5,minim:[2,4],minimalsampl:0,minimum:[0,4],minut:[0,4],mode:[0,1,4,5],modem:[3,4,5],modul:[0,4,5],moment:[4,5],monitor:4,more:[3,4,5],most:[1,4,5],motiv:2,move:1,mtu:[4,5],much:4,multi:[4,5],multilater:4,multipl:[0,4],multipoint:4,must:[0,3,4],my:4,n:0,name:[0,3],namespac:0,nano:1,narg:0,necessari:[1,3,4],necessarili:4,need:[0,2,4,5],neglig:4,neither:4,neon:0,network:[0,1,3,4,5],never:3,newer:4,newest:4,newli:4,next:[1,4],nicknam:4,no_inbound_for:3,no_outbound_for:3,nobl:0,noble_ga:0,noble_gas:0,node:[2,5],nomad:1,non:[3,4],none:[0,3,4],normal:0,notat:4,note:[0,4],noth:5,notic:4,notif:[0,3],now:[0,1,4],nt:0,num:0,number:[0,3,4],object:3,obtain:4,occur:5,off:[4,5],offer:[2,3,4],often:4,oganesson:0,old:4,onc:[4,5],one:[0,3,4,5],onli:[0,3,4,5],onlin:4,open:[0,3,4,5],openmodem:5,oper:[3,4,5],opt:4,optic:5,option:[0,1],orient:4,origin:4,original_hash:3,os:[0,4,5],ospf:4,other:[3,4],otherwis:[3,4],our:[0,4],out:[0,3,4,5],outbound:3,outgo:[0,3,4],outlin:[1,4],outward:4,over:[0,3,4,5],overal:4,overcom:4,overhead:4,overrid:0,overview:4,own:[0,1,3,4],owner:3,p:[0,4],pack:0,packb:0,packet:[0,2,5],packet_callback:0,packet_deliv:0,packet_receipt:[0,3],packet_timed_out:0,packet_typ:3,packetreceipt:[0,3],pad:5,page:[2,4],pair:4,palm:0,paramet:3,pars:0,parse_arg:0,parser:0,part:[0,4],particip:[2,4],pass:[0,3,4],path:[0,1,3,4],path_respons:3,pathfind:[],pattern:4,payload:[3,4],peach:0,peer:[3,4],peer_pub_byt:3,peer_sig_pub_byt:3,peopl:4,per:[4,5],percent:0,perfect:4,perform:4,period:4,persecut:4,person:4,philosophi:4,physic:4,pi:[0,4,5],piec:4,ping:1,pip3:1,pip:1,pkcs7:5,place:4,plain:[0,3,4],plain_mdu:3,plaintext:[0,3],platform:4,pleas:[0,5],plenti:4,plu:4,pmr:4,point:4,pomelo:0,port:[4,5],possess:4,possibl:[4,5],potenti:[0,4],practic:[4,5],pre:[3,4],predict:4,prefer:4,prepar:0,presenc:3,press:0,pretend:4,pretti:4,prettyhexrep:0,previou:0,previous:[3,4],primari:4,principl:[4,5],print:0,print_filelist:0,print_help:0,print_menu:0,prioriti:4,prioritis:2,privaci:5,privat:[3,4,5],probabl:[0,4,5],procedur:4,process:[1,3,4],product:3,program:[0,2,3,4],program_setup:0,programm:4,programmat:4,progress:[0,3,5],progress_callback:3,project:1,prompt:0,proof:[0,3,4],proof_requested_callback:3,proof_strategi:3,propag:4,protocol:[1,2,5],prove:[0,4],prove_al:[0,3],prove_app:3,prove_non:3,proven:[3,4],provid:[0,1,2,3,4,5],prv_byte:3,pub_byt:3,public_inform:0,purchas:[4,5],purg:3,purpos:[3,4],purposefulli:4,put:0,py:[0,1],pyseri:1,python3:1,python:[4,5],q:0,queri:0,queue:4,quinc:0,quit:0,r:[0,4],radio:[3,4,5],radiu:4,radon:0,rais:[0,3],rand:4,randint:0,random:[0,3,4],randomli:[0,4],rang:[0,4,5],raspberri:[4,5],rate:0,rb:0,re:[0,3,4],reach:2,reachabl:[0,3,4],read:[0,1,4],readabl:[0,3,4],readi:[0,1],readili:5,real:5,reason:4,reassembl:4,recal:[0,3],recall_app_data:3,recap:4,receipt:[0,2,4],receiv:[0,3,4],received_announc:[0,3],recip:1,recipi:4,recommend:[0,4],reconstruct:4,record:4,recreat:4,refer:[0,1,2],regard:4,regist:[0,3],register_announce_handl:[0,3],rel:[4,5],releas:[1,4],relev:[0,3],reli:4,reliabl:[4,5],rem:0,remain:4,rememb:4,remot:[0,5],remotesensor:4,repeat:1,replac:[1,4],repli:0,replic:4,reply_data:0,reply_text:0,repositori:1,repres:4,represent:[0,4],request:[0,3,4],request_destin:0,request_packet:0,request_path:[0,3],requir:[0,4,5],research:5,resend:3,reserv:4,resili:5,resourc:[0,2],resource_callback:3,resource_sending_conclud:0,resource_strategi:3,respond:[0,3],rest:5,result:[0,4],reticulum:0,retransmiss:4,retransmit:4,retri:4,reveal:4,review:5,right:[],rn:[0,1,3],rnode:[4,5],robot:4,rotat:4,round:[0,3],rout:[3,4,5],rprogress:0,rsa:[],rtt:[0,4],rttstring:0,rule:4,run:[0,1,3,4,5],runtim:4,rw:4,s:[0,1,4,5],said:4,same:[1,3,4],satisfi:4,save:[3,4],save_error:0,saved_filenam:0,scenario:[1,4],screen:0,search:2,second:[0,3,4,5],secreci:[3,4,5],section:4,secur:[4,5],see:[0,3,4],seen:4,segment_index:3,select:0,self:[0,5],send:[0,3,4],sender:[0,4],sensibl:1,sensor:4,sent:[0,3,4],sentiment:4,separ:4,sequenc:[0,3,4,5],serial:[4,5],serv:[0,4],serve_path:0,server:[0,1],server_callback:0,server_destin:0,server_fil:0,server_ident:0,server_link:0,server_loop:0,server_packet_receiv:0,session:4,set:[0,3,4,5],set_default_app_data:3,set_delivery_callback:[0,3],set_link_closed_callback:0,set_link_established_callback:[0,3],set_packet_callback:[0,3],set_proof_requested_callback:3,set_proof_strategi:[0,3],set_resource_callback:3,set_resource_concluded_callback:[0,3],set_resource_started_callback:[0,3],set_resource_strategi:[0,3],set_timeout:[0,3],set_timeout_callback:3,setdaemon:0,setup:[0,2],sever:3,sha256:5,sha:[3,4],shall:4,share:[1,3,4],shelf:[4,5],shortest:4,should:[0,3,4,5],should_allow_unencrypt:3,should_quit:0,should_use_implicit_proof:3,shown:0,side:5,sign:[3,4],signatur:[3,4,5],similar:5,simpl:[0,4,5],simplest:4,simpli:[0,1,4],simplic:4,sinc:[0,3,4],singl:[0,3,4],singular:4,situat:4,size:[0,3,4],size_str:0,sleep:0,slice:0,slow:[0,4],small:[0,4],so:[0,1,4,5],softwar:[4,5],some:[0,1,4],someth:4,somethign:0,soon:3,sort:4,sourc:[0,1,4,5],space:[0,5],span:4,special:4,specif:[0,2,3,5],specifi:[0,3],spectrum:4,split:0,sponsor:5,stabl:[4,5],stack:[0,1,4,5],stage:4,standard:4,start:[0,2,3,4],startup:0,state:0,station:4,statist:0,statu:[0,2,3,4],stdout:0,step:1,still:[0,4],stop:5,store:[0,4],store_tru:0,str:0,strategi:3,stream:4,strength:5,strictli:4,string:[0,3],structur:4,subject:4,subsequ:4,successful:3,successfulli:0,sucessfulli:4,suffic:4,suffici:4,suffix:0,suit:[1,4],suitabl:[0,4],suppli:[3,4],support:[0,2,4],sy:0,symlink:1,symmetr:[3,4],system:[0,2,3,5],t:[0,1,4],tabl:4,take:[0,1,4,5],taken:[0,4],tangerin:0,target:0,tcp:[4,5],tdata:0,teardown:[0,3],teardown_reason:0,teffect:0,tell:0,temperatur:4,ten:4,term:4,termin:3,terminolog:4,test:4,text:[0,4],tfile:0,than:[0,4],thei:[0,3,4],them:[0,4],thereaft:4,therefor:[4,5],thi:[0,1,2,3,4],though:4,thourough:5,thread:0,three:4,through:[4,5],throughout:4,throughput:[4,5],thu:4,ti:[0,4],time:[0,1,3,4],timeout:[0,3],timeout_callback:0,timeoutarg:0,timestr:0,tnc:[3,5],to_fil:3,todai:4,todo:[],togeth:4,token:[3,4],too:[0,4],tool:5,top:4,topic:4,topolog:4,total:[4,5],total_s:0,touch:5,toward:[0,4],traffic:[0,3,4],tramsit:[],transceiv:[4,5],transfer:[0,3,4,5],transfer_s:0,transmiss:4,transmit:[0,4],transpar:4,transport:[0,2,5],transport_en:3,transport_id:3,transport_typ:3,travers:4,treat:4,tri:0,trip:[0,3],trivial:5,truli:4,truncat:[3,4],truncated_hash:3,truncated_hashlength:3,trust:4,trustless:[4,5],ttime:0,ttransfer:0,tunnel:[4,5],tupl:3,two:[0,4],type:[0,2,3],typeerror:3,udp:[4,5],umsgpack:0,uncencrypt:0,underli:5,understand:[1,2],unencrypt:[0,3,4],unequivoc:4,unforg:5,uninterest:0,uniqu:[4,5],unit:0,unknown:[0,3,4],unless:[1,3,4],unlicens:4,unpack:0,unpackb:0,unsupport:3,until:[0,3,4],unwant:4,up:[0,4,5],updat:[0,3],upon:[0,4],urandom:5,us:[0,2,3,4],usabl:4,usag:[],usb:[4,5],useabl:4,user:[0,1,3,4],user_input:0,userland:5,utf:0,util:[0,1,4],utilis:[4,5],valid:[0,3,4],valu:4,valueerror:[0,3],variabl:0,varieti:[4,5],variou:[0,4],ve:1,vendor:0,veri:[3,4,5],verif:[3,4],verifi:[0,4],versa:5,version:3,vhf:4,via:[1,4],vice:5,view:4,visibl:0,wa:[0,3,4,5],wai:[0,1,4],wait:[0,4],want:[0,1,4,5],warrant:5,wb:0,we:[0,4],well:[3,4,5],went:0,what:[0,1,2,3,4],whatev:4,when:[0,1,3,4],whenev:3,where:[2,3,4],whereupon:4,whether:[0,3,4],which:[0,1,3,4],who:4,wide:[4,5],wifi:[4,5],wildcard:0,window:4,wire:[4,5],wish:4,within:[0,3,4],won:0,work:[4,5],world:5,would:4,write:[0,3],written:4,wrong:0,x25519:[3,4,5],x:4,xenon:0,y:0,ye:4,year:4,yet:[0,4],yi:0,you:[0,1,2,3,4,5],your:[0,1,4,5],yourself:[4,5],z:0,zero:3,zi:0},titles:["Examples","Getting Started Fast","Reticulum Network Stack Manual","API Reference","Understanding Reticulum","What is Reticulum?"],titleterms:{"1":[],"2":[],"class":3,"function":4,"public":4,"try":1,The:4,announc:[0,4],api:3,base:1,basic:4,binari:4,broadcast:0,can:5,caveat:5,current:5,deliveri:[],destin:[3,4],detail:4,develop:1,devic:5,doe:5,echo:0,emptor:5,establish:4,exampl:0,fast:1,filetransf:0,format:4,further:4,get:[1,4],goal:4,ident:[3,4],indic:2,interfac:5,introduct:4,kei:4,link:[0,3,4],manual:2,mechan:4,minim:0,motiv:4,name:4,network:2,node:4,offer:5,packet:[3,4],particip:1,pathfind:[],prioritis:4,program:1,protocol:4,proven:[],reach:4,receipt:3,refer:[3,4],resourc:[3,4],reticulum:[1,2,3,4,5],setup:4,specif:4,stack:2,start:1,statu:5,step:[],support:5,system:4,tabl:2,transport:[3,4],type:[4,5],understand:4,us:[1,5],what:5,where:5}}) \ No newline at end of file diff --git a/docs/manual/understanding.html b/docs/manual/understanding.html index e1fb947..443694e 100644 --- a/docs/manual/understanding.html +++ b/docs/manual/understanding.html @@ -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 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.

-

The combined bandwidth cost of setting up a link is 3 packets totalling 409 bytes (more info in the +

The combined bandwidth cost of setting up a link is 3 packets totalling 240 bytes (more info in the Binary Packet Format 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 radio channel, 100 concurrent links will still leave 95% channel capacity for actual data.

@@ -762,8 +762,8 @@ proof 11 - Path Request : 33 bytes - Announce : 151 bytes - - Link Request : 182 bytes - - Link Proof : 141 bytes + - Link Request : 77 bytes + - Link Proof : 77 bytes - Link RTT packet : 86 bytes - Link keepalive : 14 bytes diff --git a/docs/manual/whatis.html b/docs/manual/whatis.html index 9499fa7..a2beffd 100644 --- a/docs/manual/whatis.html +++ b/docs/manual/whatis.html @@ -81,7 +81,7 @@
  • Efficient link establishment

      -
    • Total bandwidth cost of setting up a link is only 409 bytes

    • +
    • Total bandwidth cost of setting up a link is only 3 packets, totalling 240 bytes

    • Low cost of keeping links open at only 0.62 bits per second

  • diff --git a/docs/source/understanding.rst b/docs/source/understanding.rst index ecc106f..8acb773 100644 --- a/docs/source/understanding.rst +++ b/docs/source/understanding.rst @@ -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 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 409 bytes (more info in the +The combined bandwidth cost of setting up a link is 3 packets totalling 240 bytes (more info in the :ref:`Binary Packet Format` 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 radio channel, 100 concurrent links will still leave 95% channel capacity for actual data. @@ -699,7 +699,7 @@ Binary Packet Format - Path Request : 33 bytes - Announce : 151 bytes - - Link Request : 182 bytes - - Link Proof : 141 bytes + - Link Request : 77 bytes + - Link Proof : 77 bytes - Link RTT packet : 86 bytes - Link keepalive : 14 bytes \ No newline at end of file diff --git a/docs/source/whatis.rst b/docs/source/whatis.rst index eb15688..66f1b8e 100644 --- a/docs/source/whatis.rst +++ b/docs/source/whatis.rst @@ -55,7 +55,7 @@ What does Reticulum Offer? * Efficient link establishment - * Total bandwidth cost of setting up a link is only 409 bytes + * Total bandwidth cost of setting up a link is only 3 packets, totalling 240 bytes * Low cost of keeping links open at only 0.62 bits per second