From:             boen dot robot at gmail dot com
Operating system: Windows Server 2008 R2
PHP version:      5.5.0
Package:          Streams related
Bug Type:         Bug
Bug description:stream_select misleads when TLS socket is used

Description:
------------
When stream_select() is called on a socket stream created by
stream_socket_client() which uses TLS (with ADH), it seems to report too
early. That is, it would report that that the stream can be read, but then
when you try to read it, it would block, and potentially fail.

The exact same code, if called without encryption, would always work just
fine. Also, if right before receiving, the script is made to sleep for a
while (in my case, about 100 miliseconds did the trick), the script is also
fine.

Sample code is hard to give, as this occurs only when the server sends
large enough data at once over the encrypted connection, and I seem to be
unable to mock a TLS+ADH server with PHP (which is a separate issue that,
at this point, could be just me being stupid).

I *think* the issue might be that stream_select() reports on the underlying
socket (i.e. the data being received before decryption), rather than the
*readable data* from the socket, while fread() blocks until there's at
least 1 byte of readable data to be read. But this shouldn't be so IMHO.

Note that this occurs not just with PHP 5.5.0, but also the latest releases
of 5.4.16 and 5.3.26, and at least as early as 5.3.8.

Test script:
---------------
NOTE: This script is an "approximation" so to speak, in that it
demonstrates the exact settings for the client where this occurs, but due
to the lack of a mock server, it's not confirmed to always fail.

<?php
$socket = stream_socket_client(
        'tls://example.com:8729',
        $errno,
        $errstr,
        2,
        STREAM_CLIENT_CONNECT,
        stream_context_create(
                array('ssl' => array('ciphers' => 'ADH'))
        )
);

fwrite($socket, chr(6) . '/login' . chr(0));

$r = array($socket);
$w = $e = null;

if (1 === stream_select($r, $w, $e, null)) {
    echo fread($socket, 1);
} else {
    echo 'stream_select() returned with errors';
}


Expected result:
----------------
stream_select() should only report the encrypted socket as readable if
there's at least 1 byte of readable data in the buffer that can be read by
fread().

Actual result:
--------------
stream_select() reports the encrypted socket as readable, but fread()
blocks, and may even time out.

-- 
Edit bug report at https://bugs.php.net/bug.php?id=65137&edit=1
-- 
Try a snapshot (PHP 5.4):   
https://bugs.php.net/fix.php?id=65137&r=trysnapshot54
Try a snapshot (PHP 5.3):   
https://bugs.php.net/fix.php?id=65137&r=trysnapshot53
Try a snapshot (trunk):     
https://bugs.php.net/fix.php?id=65137&r=trysnapshottrunk
Fixed in SVN:               https://bugs.php.net/fix.php?id=65137&r=fixed
Fixed in release:           https://bugs.php.net/fix.php?id=65137&r=alreadyfixed
Need backtrace:             https://bugs.php.net/fix.php?id=65137&r=needtrace
Need Reproduce Script:      https://bugs.php.net/fix.php?id=65137&r=needscript
Try newer version:          https://bugs.php.net/fix.php?id=65137&r=oldversion
Not developer issue:        https://bugs.php.net/fix.php?id=65137&r=support
Expected behavior:          https://bugs.php.net/fix.php?id=65137&r=notwrong
Not enough info:            
https://bugs.php.net/fix.php?id=65137&r=notenoughinfo
Submitted twice:            
https://bugs.php.net/fix.php?id=65137&r=submittedtwice
register_globals:           https://bugs.php.net/fix.php?id=65137&r=globals
PHP 4 support discontinued: https://bugs.php.net/fix.php?id=65137&r=php4
Daylight Savings:           https://bugs.php.net/fix.php?id=65137&r=dst
IIS Stability:              https://bugs.php.net/fix.php?id=65137&r=isapi
Install GNU Sed:            https://bugs.php.net/fix.php?id=65137&r=gnused
Floating point limitations: https://bugs.php.net/fix.php?id=65137&r=float
No Zend Extensions:         https://bugs.php.net/fix.php?id=65137&r=nozend
MySQL Configuration Error:  https://bugs.php.net/fix.php?id=65137&r=mysqlcfg

Reply via email to