Reticulum/RNS
Jeremy O'Brien 794e437f6d Channel: prevent sequence holes and ghost envelopes when sending on a dying outlet
RNSChannelOutlet.send() can return a packet that never reached the wire
(link not ACTIVE, no capable interface, etc). The old Channel.send()
queued the envelope in _tx_ring before calling outlet.send(), then
tried to rewind _next_sequence and remove the envelope if the outlet
returned a failed packet. Two problems:

- Between queueing and outlet.send() returning, _tx_ring held an
envelope with packet.raw=None. Any worker thread iterating the
ring (timeout fire, proof callback) crashed in get_packet_id's
packet.get_hash() with a TypeError on None.raw.

- The rewind was only safe for a single-threaded sender: it checked
"is _next_sequence one past mine?" and skipped the rewind otherwise.
Under concurrent senders, the rewind silently failed, leaving a
hole in the on-wire sequence stream. The receiver's contiguous
seqnum rule then stalled the channel permanently with no error.

This fix serializes the reservation-and-transmit pair with a per-channel
_send_lock so the rewind is always correct, and defers queueing until
outlet.send() returns a real packet so _tx_ring never contains a
packet-less envelope. _packet_tx_op() and get_packet_id() now also
defensively skip/return-None for packet-less envelopes.

Also handle the small race where a proof arrives between outlet.send()
registering the receipt and us installing the delivery callback: after
registration, re-read the receipt status and synthesize the
_packet_delivered() call if it's already DELIVERED.
2026-05-19 14:52:59 -04:00
..
Cryptography Refactoring work for rnid 2026-05-07 14:11:49 +02:00
Interfaces Use canonical Transport interface list add/removes. Improved announce cache cleaning. Adjusted logging. 2026-05-15 17:08:22 +02:00
Utilities rnsh: don't wait forever for rns operations when timeout isn't set 2026-05-19 07:46:50 -04:00
vendor Added validate.py for spec validation 2026-05-17 20:27:16 +02:00
__init__.py Cleanup 2026-05-11 23:31:25 +02:00
_version.py Updated version 2026-05-19 00:51:12 +02:00
Buffer.py Fixed bz2 decompression bomb vulnerability in Resource transfer assembly and Buffer StreamDataMessage unpacking. 2026-04-22 12:43:16 +02:00
Channel.py Channel: prevent sequence holes and ghost envelopes when sending on a dying outlet 2026-05-19 14:52:59 -04:00
Destination.py Periodically clean known destinations data based on local relevance 2026-04-21 13:21:23 +02:00
Discovery.py Use canonical Transport interface list add/removes. Improved announce cache cleaning. Adjusted logging. 2026-05-15 17:08:22 +02:00
Identity.py Don't iterate known_destinations directly; it can change during iteration 2026-05-19 07:46:50 -04:00
Link.py Tear down active and pending links before interface detach 2026-04-26 11:30:22 +02:00
Packet.py Transport logic for path request ingress and egress control 2026-05-09 01:14:40 +02:00
Resolver.py Updated license 2025-04-15 20:19:33 +02:00
Resource.py Improved logging performance 2026-05-06 01:03:43 +02:00
Reticulum.py Use canonical Transport interface list add/removes. Improved announce cache cleaning. Adjusted logging. 2026-05-15 17:08:22 +02:00
Transport.py Use canonical Transport interface list add/removes. Improved announce cache cleaning. Adjusted logging. 2026-05-15 17:08:22 +02:00