fix: survive busy sessions without exhausting file descriptors
The peer listener died with "Too many open files (os error 24)" on any long-lived non-daemon session: only the daemon raised RLIMIT_NOFILE, and peer sockets were unbounded — no idle reaping, no deadlines on accepted transfer streams, and one peer could hold two connections under split registry identities. - raise the open-file limit at the top of run(), for every entry point, and warn from Client::connect when the soft limit is below 1024 - reap peer control connections idle for five minutes; a clean disconnect no longer discards the peer's queued uploads - give listener-supplied download streams and upload serving the same read/write deadlines dialled sockets already had - register inbound peers under their plain username so the registry holds one connection per peer, and announce them like pierced ones - hold the registry lock across actor spawn + insert and surface thread-spawn failure, so an instantly-dead peer cannot leave a zombie entry
This commit is contained in:
@@ -42,6 +42,17 @@ pub fn serve_file(
|
||||
})?;
|
||||
let mut stream =
|
||||
TcpStream::connect_timeout(&socket, Duration::from_secs(20))?;
|
||||
// A downloader that connects and then goes silent must cost seconds, not
|
||||
// the rest of the session: without deadlines a wedged `read_exact` (or a
|
||||
// zero-window `write_all`) holds this thread, the socket, the open file,
|
||||
// and — because the upload stays InProgress — an upload slot, forever.
|
||||
// Thirty seconds of total silence is a dead transfer, not a slow one: even
|
||||
// a slow reader drains some buffer within that. The write deadline is
|
||||
// deliberately looser than the download side's 5s: bulk data flows this
|
||||
// way, and a congested but living peer may hold the send buffer full far
|
||||
// longer than a peer draining our tiny control frames ever would.
|
||||
stream.set_read_timeout(Some(Duration::from_secs(30)))?;
|
||||
stream.set_write_timeout(Some(Duration::from_secs(30)))?;
|
||||
stream.set_nodelay(true).ok();
|
||||
|
||||
// PeerInit(F) + the 4-byte token in a single write so they coalesce.
|
||||
|
||||
Reference in New Issue
Block a user