Optimised link establishment

This commit is contained in:
Mark Qvist 2021-05-20 20:32:08 +02:00
parent cf9934810b
commit d68cfaa8f7
13 changed files with 42 additions and 38 deletions

View File

@ -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?

View File

@ -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)

View File

@ -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):

View File

@ -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

Binary file not shown.

View File

@ -429,7 +429,7 @@ terms of bandwidth, so it can be used just for a short exchange, and then recrea
also rotate encryption keys. The link can also be kept alive for longer periods of time, if this is
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<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
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

View File

@ -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

View File

@ -767,7 +767,7 @@ from a the <em>send()</em> method of a <a class="reference internal" href="#api-
<dl class="py attribute">
<dt class="sig sig-object py" id="RNS.Link.KEEPALIVE">
<span class="sig-name descname"><span class="pre">KEEPALIVE</span></span><em class="property"> <span class="pre">=</span> <span class="pre">180</span></em><a class="headerlink" href="#RNS.Link.KEEPALIVE" title="Permalink to this definition"></a></dt>
<span class="sig-name descname"><span class="pre">KEEPALIVE</span></span><em class="property"> <span class="pre">=</span> <span class="pre">360</span></em><a class="headerlink" href="#RNS.Link.KEEPALIVE" title="Permalink to this definition"></a></dt>
<dd><p>Interval for sending keep-alive packets on established links in seconds.</p>
</dd></dl>

File diff suppressed because one or more lines are too long

View File

@ -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 <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 409 bytes (more info in the
<p>The combined bandwidth cost of setting up a link is 3 packets totalling 240 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 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>
@ -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
</pre></div>

View File

@ -81,7 +81,7 @@
</li>
<li><p>Efficient link establishment</p>
<ul>
<li><p>Total bandwidth cost of setting up a link is only 409 bytes</p></li>
<li><p>Total bandwidth cost of setting up a link is only 3 packets, totalling 240 bytes</p></li>
<li><p>Low cost of keeping links open at only 0.62 bits per second</p></li>
</ul>
</li>

View File

@ -429,7 +429,7 @@ terms of bandwidth, so it can be used just for a short exchange, and then recrea
also rotate encryption keys. The link can also be kept alive for longer periods of time, if this is
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<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
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

View File

@ -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