|
php.net | support | documentation | report a bug | advanced search | search howto | statistics | random bug | login |
[2015-11-18 20:33 UTC] lcharron at meditech dot com
Description:
------------
You should be able to obtain the socket from a socket-based SSL stream so that socket options (ex. SO_KEEPALIVE) can be set.
The documentation makes no mention that this is not possible.
Test script:
---------------
$host = "host";
$port = "443";
$stream = stream_socket_client("ssl://{$host}:{$port}");
$socket = socket_import_stream($stream);
if ($socket) {
socket_set_option($socket, SOL_SOCKET, SO_KEEPALIVE, 1);
}
Expected result:
----------------
socket_import_stream should return the underlying socket so options can be set.
Actual result:
--------------
socket_import_stream returns null and the following warning is emitted:
Warning: socket_import_stream(): cannot represent a stream of type tcp_socket/ssl as a Socket Descriptor in ...
PatchesPull Requests
Pull requests:
HistoryAllCommentsChangesGit/SVN commits
|
|||||||||||||||||||||||||||||||||||||
Copyright © 2001-2025 The PHP GroupAll rights reserved. |
Last updated: Tue Dec 02 09:00:01 2025 UTC |
This still appears to an issue (at least in PHP 7.3.26). However, I may have found a workaround, albeit a convoluted one and one of which I still don't know the full implications for. I still need to do more testing to actually see what my workaround means for the actual state of the low-level socket, that now can be acquired with socket_import_stream(), and the stream's encryption state when fiddling with the low-level socket. ========== WARNING Because this involves security-sensitive stuff, USE THIS AT YOUR OWN RISK and thoroughly test it, to verify that the intended encryption is not broken! ========== Here's my temporary workaround: ---------- $host = "host"; $port = "443"; $stream = stream_socket_client( "ssl://{$host}:{$port}" ); stream_socket_enable_crypto( $stream, false ); $socket = socket_import_stream( $stream ); var_dump( gettype( $socket ) ); // string(8) "resource" // If the stream is blocked, it needs to be temporarily unblocked first, // otherwise you'll get the warning: SSL/TLS already set-up for this stream // See https://github.com/php/php-src/blob/3e01f5afb1b52fe26a956190296de0192eedeec1/ext/openssl/xp_ssl.c#L1635 $blocked = stream_get_meta_data( $stream )[ 'blocked' ]; if( $blocked ) { stream_set_blocking( $stream, false ); } // Be sure to apply the correct $crypto_type, if you've used a different one before stream_socket_enable_crypto( $stream, true, STREAM_CRYPTO_METHOD_ANY_CLIENT ); // Maybe re-apply blocking if( $blocked ) { stream_set_blocking( $stream, true ); } ----------