php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #52323 php_network_connect_socket doesn't return all errors correctly
Submitted: 2010-07-12 23:07 UTC Modified: 2013-02-18 00:34 UTC
Votes:2
Avg. Score:4.0 ± 1.0
Reproduced:2 of 2 (100.0%)
Same Version:2 (100.0%)
Same OS:1 (50.0%)
From: onno at flox dot org Assigned: pajoye (profile)
Status: No Feedback Package: Sockets related
PHP Version: trunk-SVN-2010-07-12 (SVN) OS:
Private report: No CVE-ID: None
View Add Comment Developer Edit
Anyone can comment on a bug. Have a simpler test case? Does it work for you on a different platform? Let us know!
Just going to say 'Me too!'? Don't clutter the database with that please — but make sure to vote on the bug!
Your email address:
MUST BE VALID
Solve the problem:
18 + 20 = ?
Subscribe to this entry?

 
 [2010-07-12 23:07 UTC] onno at flox dot org
Description:
------------
php_network_connect_socket doesn't return all connection errors (like ECONNREFUSED) correctly in all cases.

When error_string is NULL, "ret" isn't set to -1, even when "error" is set. This can cause problems on all platforms. The ftp extension for example will only detect a socket error once it tries to read the socket, instead of directly after the call to php_network_connect_socket.

On Windows, an additional problem exists because of the poll() emulation in php_poll2: php_network_connect_socket polls for PHP_POLLREADABLE|POLLOUT, which by php_poll2 is mapped to the readfds and writefds parameters of select(). In winsock however, connect() errors are returned in exceptfds, not in writefds like they are in POSIX. This means the select() call will only return once its timeout has passed and that php_network_connect_socket will incorrectly return PHP_TIMEOUT_ERROR_VALUE. This behaviour causes undesired delays in many functions that (try to) create network connections.

An example of this is the long delay that is observed when connecting to a MySQL-server using mysqlnd and a hostname that has both an IPv6 and an IPv4 address: connecting using the IPv6 address will quickly fail, but because of this bug it will take mysql.connect_timeout seconds before the IPv4 address is tried.


Patches

php-connect-errors.patch (last revision 2010-07-12 21:08 UTC by onno at flox dot org)

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2010-07-18 21:35 UTC] felipe@php.net
-Status: Open +Status: Assigned -Assigned To: +Assigned To: pajoye
 [2010-09-07 11:59 UTC] pajoye@php.net
-Status: Assigned +Status: Feedback
 [2010-09-07 11:59 UTC] pajoye@php.net
hi,

This is related to #50953, can you take a look at the patch and see if that matches what you have done here? Or if we need to apply your patch instead, or part of it.
 [2010-09-07 12:46 UTC] cataphract@php.net
-: onno@flox.org +: spam at geleia dot net
 [2010-09-07 12:46 UTC] cataphract@php.net
I think it makes moresense leave php_poll2 untouched.

See http://linux.die.net/man/2/poll, which is being emulated and http://msdn.microsoft.com/en-us/library/ms740141(VS.85).aspx which is being used for the implementation.

The patch in this bug report fills the exceptfds if POLLERR is given, instead of POLLPRI. However, POLLERR is supposed to be output only as per poll(2)'s specification.

This way,

* PHP_POLLREADABLE can be given to check if there's data to be read -- although, like the comment in php_poll2 says, it can also mean POLLHUP and POLLERR. Since we "can't know this without probing", we default to retuning POLLIN.
* POLLOUT can be given to check if data can be sent/will not block. In windows, it can also mean a nonblocking connection was successful. We can't distinguish between the two, so we return POLLOUT.
* POLLPRI can be given to check if processing a connect call (nonblocking), connection attempt failed or OOB data is available for reading (only if SO_OOBINLINE is disabled). Again, we can't distinguish between the two, so we return POLLPRI.

It has to be caller that disambiguates the return value. In Windows, in case of a nonblocking connect call, we should pass POLLOUT|POLLPRI. When read the return, we know that POLLOUT means the connection was successful and POLLPRI means the connection failed (see patch for bug #50953).
 [2010-09-07 12:54 UTC] pajoye@php.net
-: spam@geleia.net +: onno at flox dot org
 [2010-09-07 13:19 UTC] cataphract@php.net
+1 for the first half of the patch.

It doesn't make sense that the return value varies according to whether the caller is interested in the error string or not...
 [2010-09-08 12:25 UTC] pajoye@php.net
Automatic comment from SVN on behalf of pajoye
Revision: http://svn.php.net/viewvc/?view=revision&revision=303166
Log: - Fix bug #52323, return value of php_network_connect_socket should be set even if the caller does not care about the error_string
 [2010-09-08 12:33 UTC] pajoye@php.net
The error part of the patch has been applied to 5.3 and trunk. I think the rest of this issue is fixed as well. However I would like to hear from you to be sure that what we've done fix the problem for your cases as well (just to be sure).
 [2010-09-08 13:51 UTC] pajoye@php.net
Automatic comment from SVN on behalf of pajoye
Revision: http://svn.php.net/viewvc/?view=revision&revision=303172
Log: - fix the fix for bug #52323
 [2013-02-18 00:34 UTC] php-bugs at lists dot php dot net
No feedback was provided. The bug is being suspended because
we assume that you are no longer experiencing the problem.
If this is not the case and you are able to provide the
information that was requested earlier, please do so and
change the status of the bug back to "Open". Thank you.
 
PHP Copyright © 2001-2021 The PHP Group
All rights reserved.
Last updated: Tue Nov 30 13:03:49 2021 UTC