Skip to content

Stream Socket Timeout #11175

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
mohamedallou opened this issue May 2, 2023 · 6 comments · Fixed by ThePHPF/thephp.foundation#90
Closed

Stream Socket Timeout #11175

mohamedallou opened this issue May 2, 2023 · 6 comments · Fixed by ThePHPF/thephp.foundation#90

Comments

@mohamedallou
Copy link

mohamedallou commented May 2, 2023

Description

The following code:

<?php
$socket = stream_socket_server("tcp://0.0.0.0:8080", $errno, $errstr);
if (!$socket) {
    echo "$errstr ($errno)<br />\n";
} else {
    while ($conn = stream_socket_accept($socket, -1)) {
        fwrite($conn, 'The local time is ' . date('n/j/Y g:i a') . "\n");
        fclose($conn);
    }
    fclose($socket);
}

Resulted in this output:

Warning: stream_socket_accept(): Accept failed: Operation timed out in ....server.php

But I expected this output instead:

The expected behaviour until php ** 8.1** is to make this function wait indefinitely to incoming connections, just as in socket_accept, by setting the timeout to -1. But it times out immediately

The setting of default_socket_timeout to a negative value via init_set does not fix the problem as well.

PHP Version

PHP 8.2.5

Operating System

No response

@KapitanOczywisty
Copy link

I cannot reproduce that on linux nor windows, can you provide a bit more information about operating system and if this script is executed in console or from http (fpm, apache)?
Does error occur immediately when script is executed or when trying to connect?
Does timeout still happen when you use positive integer e.g. 3600?

@mohamedallou
Copy link
Author

mohamedallou commented May 2, 2023

This was tested on MacOs X php 8.2.5 in a console script. The timeout does not happen if we use positive numbers, .i.e if we set 5 seconds it will time out after 5 second if there are no request. This works correctly. The only problem was with negative value -1 which times out immediately.

@mohamedallou
Copy link
Author

On the other side, if we replicate this logic using the socket api: socket_create. socket_listen... Everything works fine.

@KapitanOczywisty
Copy link

This was tested on MacOs X php 8.2.5 in a console script.

M1 or Intel? I cannot test that further unfortunately.

@mohamedallou
Copy link
Author

I used M1, Mac OS 13.0 and php 8.2.5

@nielsdos
Copy link
Member

nielsdos commented May 2, 2023

I have a strong feeling this is due to the undefined behaviour issue in #11177. Because when UB happens the compiler is allowed to generate any code it, i.e. the -1 situation "does not happen" according to the compiler.
An extreme example is this: https://godbolt.org/z/Ehb6qY68G where the return value is not even emitted under ARM while it is emitted under x86-64. This could explain why you see it in M1 but we can't on x86.

nielsdos added a commit to nielsdos/php-src that referenced this issue May 2, 2023
…viour

A negative value like -1 may overflow and cause incorrect results in the
timeout variable, which causes an immediate timeout. As this is caused
by undefined behaviour the exact behaviour depends on the compiler, its
version, and the platform.

A large overflow is also possible, if an extremely large timeout value
is passed we also set an indefinite timeout. This is because the timeout
value is at least a 64-bit number and waiting for UINT64_MAX/1000000
seconds is waiting about 584K years.
nielsdos added a commit that referenced this issue May 3, 2023
* PHP-8.1:
  Fix GH-11178: Segmentation fault in spl_array_it_get_current_data (PHP 8.1.18)
  Fix GH-11175 and GH-11177: Stream socket timeout undefined behaviour
  Fix GH-9068: Conditional jump or move depends on uninitialised value(s)
nielsdos added a commit that referenced this issue May 3, 2023
* PHP-8.2:
  Fix GH-11178: Segmentation fault in spl_array_it_get_current_data (PHP 8.1.18)
  Fix GH-11175 and GH-11177: Stream socket timeout undefined behaviour
  Fix GH-9068: Conditional jump or move depends on uninitialised value(s)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
5 participants
@bukka @nielsdos @mohamedallou @KapitanOczywisty and others