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 - Sequencing, transfer coordination and checksumming is automatic
- The API is very easy to use, and provides transfer progress - The API is very easy to use, and provides transfer progress
- Efficient link establishment - 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 - Low cost of keeping links open at only 0.62 bits per second
## Where can Reticulum be used? ## Where can Reticulum be used?

View File

@ -209,14 +209,15 @@ class Destination:
self.proof_strategy = proof_strategy self.proof_strategy = proof_strategy
def receive(self, packet): def receive(self, packet):
plaintext = self.decrypt(packet.data) if packet.packet_type == RNS.Packet.LINKREQUEST:
if plaintext != None: plaintext = packet.data
if packet.packet_type == RNS.Packet.LINKREQUEST: self.incoming_link_request(plaintext, packet)
self.incoming_link_request(plaintext, packet) else:
plaintext = self.decrypt(packet.data)
if packet.packet_type == RNS.Packet.DATA: if plaintext != None:
if self.callbacks.packet != None: if packet.packet_type == RNS.Packet.DATA:
self.callbacks.packet(plaintext, packet) if self.callbacks.packet != None:
self.callbacks.packet(plaintext, packet)
def incoming_link_request(self, data, packet): def incoming_link_request(self, data, packet):
link = RNS.Link.validate_request(self, data, packet) link = RNS.Link.validate_request(self, data, packet)

View File

@ -52,7 +52,7 @@ class Link:
""" """
TIMEOUT_FACTOR = 3 TIMEOUT_FACTOR = 3
STALE_GRACE = 2 STALE_GRACE = 2
KEEPALIVE = 180 KEEPALIVE = 360
""" """
Interval for sending keep-alive packets on established links in seconds. Interval for sending keep-alive packets on established links in seconds.
""" """
@ -128,14 +128,15 @@ class Link:
self.__encryption_disabled = False 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.sig_prv = self.owner.identity.sig_prv
else: else:
self.initiator = True self.initiator = True
self.prv = X25519PrivateKey.generate()
self.sig_prv = Ed25519PrivateKey.generate()
self.fernet = None self.fernet = None
self.prv = X25519PrivateKey.generate()
self.sig_prv = Ed25519PrivateKey.generate()
self.pub = self.prv.public_key() self.pub = self.prv.public_key()
self.pub_bytes = self.pub.public_bytes( self.pub_bytes = self.pub.public_bytes(
encoding=serialization.Encoding.Raw, encoding=serialization.Encoding.Raw,
@ -155,10 +156,14 @@ class Link:
self.load_peer(peer_pub_bytes, peer_sig_pub_bytes) self.load_peer(peer_pub_bytes, peer_sig_pub_bytes)
if (self.initiator): 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.request_data = self.pub_bytes+self.sig_pub_bytes
self.packet = RNS.Packet(destination, self.request_data, packet_type=RNS.Packet.LINKREQUEST) self.packet = RNS.Packet(destination, self.request_data, packet_type=RNS.Packet.LINKREQUEST)
self.packet.pack() self.packet.pack()
self.set_link_id(self.packet) self.set_link_id(self.packet)
self.load_peer(peer_pub_bytes, peer_sig_pub_bytes)
self.handshake()
RNS.Transport.register_link(self) RNS.Transport.register_link(self)
self.request_time = time.time() self.request_time = time.time()
self.start_watchdog() self.start_watchdog()
@ -195,7 +200,7 @@ class Link:
signed_data = self.link_id+self.pub_bytes+self.sig_pub_bytes signed_data = self.link_id+self.pub_bytes+self.sig_pub_bytes
signature = self.owner.identity.sign(signed_data) 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 = RNS.Packet(self, proof_data, packet_type=RNS.Packet.PROOF, context=RNS.Packet.LRPROOF)
proof.send() proof.send()
self.had_outbound() self.had_outbound()
@ -214,15 +219,11 @@ class Link:
self.had_outbound() self.had_outbound()
def validate_proof(self, packet): def validate_proof(self, packet):
if self.initiator and len(packet.data) == Link.ECPUBSIZE+RNS.Identity.KEYSIZE//8: if self.initiator and len(packet.data) == RNS.Identity.SIGLENGTH//8:
peer_pub_bytes = packet.data[:Link.ECPUBSIZE//2] signed_data = self.link_id+self.peer_pub_bytes+self.peer_sig_pub_bytes
peer_sig_pub_bytes = packet.data[Link.ECPUBSIZE//2:Link.ECPUBSIZE] signature = packet.data[:RNS.Identity.SIGLENGTH//8]
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.destination.identity.validate(signature, signed_data): 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.rtt = time.time() - self.request_time
self.attached_interface = packet.receiving_interface self.attached_interface = packet.receiving_interface
RNS.Transport.activate_link(self) RNS.Transport.activate_link(self)
@ -258,8 +259,7 @@ class Link:
if self.owner.callbacks.link_established != None: if self.owner.callbacks.link_established != None:
self.owner.callbacks.link_established(self) self.owner.callbacks.link_established(self)
except Exception as e: except Exception as e:
RNS.log("Error occurred while processing RTT packet, tearing down link", RNS.LOG_ERROR) RNS.log("Error occurred while processing RTT packet, tearing down link. The contained exception was: "+str(e), RNS.LOG_ERROR)
traceback.print_exc()
self.teardown() self.teardown()
def get_salt(self): def get_salt(self):

View File

@ -143,6 +143,9 @@ class Packet:
if self.packet_type == Packet.ANNOUNCE: if self.packet_type == Packet.ANNOUNCE:
# Announce packets are not encrypted # Announce packets are not encrypted
self.ciphertext = self.data 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: elif self.packet_type == Packet.PROOF and self.context == Packet.RESOURCE_PRF:
# Resource proofs are not encrypted # Resource proofs are not encrypted
self.ciphertext = self.data 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 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 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 :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.
@ -699,7 +699,7 @@ Binary Packet Format
- Path Request : 33 bytes - Path Request : 33 bytes
- Announce : 151 bytes - Announce : 151 bytes
- Link Request : 182 bytes - Link Request : 77 bytes
- Link Proof : 141 bytes - Link Proof : 77 bytes
- Link RTT packet : 86 bytes - Link RTT packet : 86 bytes
- Link keepalive : 14 bytes - Link keepalive : 14 bytes

View File

@ -55,7 +55,7 @@ What does Reticulum Offer?
* Efficient link establishment * 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 * 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"> <dl class="py attribute">
<dt class="sig sig-object py" id="RNS.Link.KEEPALIVE"> <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><p>Interval for sending keep-alive packets on established links in seconds.</p>
</dd></dl> </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 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 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 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>
@ -762,8 +762,8 @@ proof 11
- Path Request : 33 bytes - Path Request : 33 bytes
- Announce : 151 bytes - Announce : 151 bytes
- Link Request : 182 bytes - Link Request : 77 bytes
- Link Proof : 141 bytes - Link Proof : 77 bytes
- Link RTT packet : 86 bytes - Link RTT packet : 86 bytes
- Link keepalive : 14 bytes - Link keepalive : 14 bytes
</pre></div> </pre></div>

View File

@ -81,7 +81,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 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> <li><p>Low cost of keeping links open at only 0.62 bits per second</p></li>
</ul> </ul>
</li> </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 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 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 :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.
@ -699,7 +699,7 @@ Binary Packet Format
- Path Request : 33 bytes - Path Request : 33 bytes
- Announce : 151 bytes - Announce : 151 bytes
- Link Request : 182 bytes - Link Request : 77 bytes
- Link Proof : 141 bytes - Link Proof : 77 bytes
- Link RTT packet : 86 bytes - Link RTT packet : 86 bytes
- Link keepalive : 14 bytes - Link keepalive : 14 bytes

View File

@ -55,7 +55,7 @@ What does Reticulum Offer?
* Efficient link establishment * 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 * Low cost of keeping links open at only 0.62 bits per second