mirror of
https://github.com/shadowsocks/shadowsocks-libev.git
synced 2026-10-28 11:43:50 +00:00
Time client-side TCP connections when idle, not only while connecting
ss-local, ss-tunnel and ss-redir only timed the upstream connect (as the C relays did), so a client that never finished its SOCKS handshake, or a stream whose peer vanished without a FIN, held a pool slot forever. With the pool now a hard cap that pauses accepting when full, enough of them stopped the listener for good. Every connection now starts with the idle deadline, connected() re-arms it, and traffic refreshes it for all kinds (the idle timeout keeps its 24 h floor, MIN_TCP_IDLE_TIMEOUT).
This commit is contained in:
+6
-3
@@ -412,6 +412,10 @@ Flow Connection::start(ss_socket_t fd) noexcept
|
||||
return close();
|
||||
}
|
||||
const TcpConfig &cfg = relay_->config_;
|
||||
// Every connection is timed from the start, so a client that never
|
||||
// finishes its handshake cannot hold a pool slot forever. Later stages
|
||||
// replace this with their own deadline.
|
||||
relay_->set_deadline(*this, Timed::idle);
|
||||
switch (cfg.kind) {
|
||||
case Kind::local:
|
||||
if (verbose) {
|
||||
@@ -443,7 +447,6 @@ Flow Connection::start(ss_socket_t fd) noexcept
|
||||
return close();
|
||||
}
|
||||
stage_ = Stage::header;
|
||||
relay_->set_deadline(*this, Timed::idle);
|
||||
update_interest();
|
||||
return Flow::proceed;
|
||||
}
|
||||
@@ -974,7 +977,7 @@ Flow Connection::server_connect(const sockaddr *target) noexcept
|
||||
Flow Connection::connected() noexcept
|
||||
{
|
||||
if (client_kind()) {
|
||||
relay_->clear_deadline(*this); // only the connect was timed
|
||||
relay_->set_deadline(*this, Timed::idle); // replaces the connect deadline
|
||||
}
|
||||
stage_ = Stage::stream;
|
||||
if (pump_to_upstream() == Flow::closed) {
|
||||
@@ -1044,7 +1047,7 @@ Connection::Pull Connection::pull(ss_socket_t fd, bool decode, FixedBuffer<kRela
|
||||
cfg.on_traffic();
|
||||
}
|
||||
}
|
||||
if (cfg.kind == Kind::server && stage_ == Stage::stream) {
|
||||
if (stage_ == Stage::stream) {
|
||||
relay_->set_deadline(*this, Timed::idle);
|
||||
}
|
||||
std::span<const std::uint8_t> in(relay_->scratch_.data(), *r);
|
||||
|
||||
Reference in New Issue
Block a user