mirror of https://github.com/ospab/ostp.git
Both produce the same reported symptom - traffic stops dead, the session itself looks fine, and only a manual reconnect recovers it. 1. protocol.rs: a retry could be charged to a frame that was never sent. The retransmit loop is budget-limited per tick, but it bumped `retries` and reset `last_sent` for every due frame regardless of whether the budget actually allowed a send. The budget is smallest exactly when loss is heaviest (it is derived from cwnd, which collapses under loss), so under real packet loss frames accumulated "phantom retries" they never received - measured at 40 retries charged for 8 frames actually sent in one tick. After max_retries+2 such rounds the zombie eviction dropped them as dead. That data was never delivered and never would be: the stream stalls permanently while pings keep flowing, so nothing upstream notices anything is wrong. Retries/timers are now only charged on an actual transmit, and the loop stops scanning once the budget is spent (sent_history is in send order, so this also keeps retransmit priority oldest-first). Covered by a new test that asserts retries charged == datagrams emitted; verified it fails against the old code. 2. bridge.rs: the stall detector was reset by datagrams that never validated. `last_valid_recv` - "last VALID recv" - was assigned before decryption, so a datagram that failed to decrypt still refreshed it on its way to the error return. Anything landing on that port kept the client convinced the tunnel was healthy: frames from a session the server had already evicted, stale retransmits, or plain garbage from an off-path source that knows the ip:port. The 25s background reconnect in handle_keepalive therefore never fired. It also made the UI health indicator report a dead tunnel as fine, and gave any off-path sender a trivial way to pin a client in a dead session indefinitely. Now set only after the datagram authenticates and decrypts. |
||
|---|---|---|
| .. | ||
| crypto | ||
| framing | ||
| congestion.rs | ||
| lib.rs | ||
| protocol.rs | ||
| relay.rs | ||