[php-src] Issue #8409: SSL handshake timeout leaves persistent connections hanging
| From: | jlesueur | Date: | Fri, 29 Apr 2022 23:01:25 +0000 |
| Subject: | [php-src] Issue #8409: SSL handshake timeout leaves persistent connections hanging | ||
| Groups: | php.bugs | ||
| Request: | Send a blank email to php-bugs+get-241343@lists.php.net to get a copy of this message | ||
Issue: https://github.com/php/php-src/issues/8409
Comment Author: jlesueur
I ran this to check if tls version matters:
```php
<?php
set_error_handler(function($errno, $errstring, $errfile, $errline, $errcontext) {
var_dump(get_resources());
exit(1);
});
$socket = stream_socket_client("tlsv1.2://redis:6379", $error_code, $error_message, 0.2,
STREAM_CLIENT_CONNECT | STREAM_CLIENT_PERSISTENT, stream_context_create(['tls' =>
['verify_peer_name' => false]]));
echo "here";
```
Sorry, this is long. tl;dr: I am proposing that the internals stream code should close connections
where the tls handshake has timed out *before* emitting a warning.
For some context, I don't think the issue I'm seeing is the same as https://github.com/phpredis/phpredis/issues/1726
How we found this issue was that we're moving to redis as a session store. We're using
persistent connections to limit the number of new connections that need to be created, however, we
still sometimes see bursts of new fpm workers coming online, triggering 500 or more new tls-enabled
connections to redis. Redis does not like this. It starts to bog down, and ssl connections start to
take longer and longer, eventually hitting our timeout (which we set somewhat aggressively at .2
seconds). In this case, the timeout is not a bug with php or redis, but a capacity problem at the
redis server. But there is some strange behavior, in that the connections where phpredis hit the
timeout while negotiating the tls handshake, are not closed until the fpm process exits. This meant
each new request created a new connection, failed tls, but left that connection open, resulting in
20k open connections on a redis host.
This was because the stream internals code emits a warning when the tls handshake times out, and
then returns the connection to the phpredis extension, and the phpredis extension attempts to work
with the connection, notices communication problems, and closes the connection, except if an error
handler exists that stops execution in the case of warnings. In that case, the connection is not
closed.