fix(client): survive the review findings on the thread-flood fix
Review of the capacity work surfaced three real defects and two gaps: - A peer dribbling bytes re-armed the 10s handshake read timeout on every read and held its accept permit forever; 128 such sockets wedged the accept loop for good. The handshake now has one deadline across all reads, plus a 4 KiB cap on buffered handshake bytes. - A capacity refusal was logged and swallowed, leaving the refused peer's queued downloads stuck until the caller's own timeout. Both registration paths now fail those downloads so the caller gets a verdict, and the listener only announces PeerConnected when the registration actually happened. - The transfer-claim was undone by the worker thread writing Queued back over it; that write is gone, so a replayed TransferResponse can no longer start a second writer on the same .part file. - Offered uploads and queue waiters joined the eviction-protected set, and the browse protection window matches the minutes a real share listing takes rather than one. Regression tests: the broker-timeout sweep failing a queued download end to end, the replay guard observed over a real socket, and the handshake deadline against a dribbling and an oversized peer.
This commit is contained in:
@@ -60,7 +60,7 @@ const BROKER_CONNECT_TIMEOUT: Duration = Duration::from_secs(20);
|
||||
|
||||
const DEFAULT_MAX_PEERS: usize = 512;
|
||||
|
||||
const BROWSE_PROTECT_WINDOW: Duration = Duration::from_mins(1);
|
||||
const BROWSE_PROTECT_WINDOW: Duration = Duration::from_mins(5);
|
||||
|
||||
/// Source of non-zero correlation tokens for server-brokered connections.
|
||||
static NEXT_CONNECT_TOKEN: AtomicU32 = AtomicU32::new(1);
|
||||
@@ -634,6 +634,9 @@ impl ClientContext {
|
||||
.collect();
|
||||
protected
|
||||
.extend(self.active_uploads.values().map(|u| u.username.clone()));
|
||||
protected.extend(self.uploads.values().map(|j| j.downloader.clone()));
|
||||
protected
|
||||
.extend(self.upload_queue.iter().map(|q| q.downloader.clone()));
|
||||
protected.extend(self.pending_serves.keys().cloned());
|
||||
protected.extend(self.pending_peer_messages.keys().cloned());
|
||||
let now = Instant::now();
|
||||
|
||||
Reference in New Issue
Block a user