php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #47289 socket_read falls into endless loop if remote host disconnects
Submitted: 2009-02-03 15:44 UTC Modified: 2009-03-26 16:36 UTC
Votes:3
Avg. Score:3.7 ± 1.9
Reproduced:0 of 0 (0.0%)
From: patryk dot szczyglowski at gmail dot com Assigned:
Status: Closed Package: Sockets related
PHP Version: 5.2.8 OS: Linux 2.6
Private report: No CVE-ID: None
Welcome back! If you're the original bug submitter, here's where you can edit the bug or add additional notes.
If you forgot your password, you can retrieve your password here.
Password:
Status:
Package:
Bug Type:
Summary:
From: patryk dot szczyglowski at gmail dot com
New email:
PHP Version: OS:

 

 [2009-02-03 15:44 UTC] patryk dot szczyglowski at gmail dot com
Description:
------------
When PHP wants to read from a blocking socket when the remote host disconnects, PHP ignores 0 return code from recv() system function and drops into endless loop.

Reproduce code:
---------------
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
socket_connect($socket, $ip, $port);
// disconnect remote host here
$rcv = socket_read($this->socket, 65536, PHP_BINARY_READ); // this line never returns

Expected result:
----------------
socket_read returns with FALSE

--- php-5.2.8/ext/sockets/sockets.c.orig	2008-10-23 22:21:30.000000000 +0200
+++ php-5.2.8/ext/sockets/sockets.c	2009-01-29 17:32:53.000000000 +0100
@@ -903,6 +903,14 @@
 		RETURN_FALSE;
 	}
 
+	if (retval == 0) {
+		php_sock->error = errno;
+		SOCKETS_G(last_error) = errno;
+
+		efree(tmpbuf);
+		RETURN_FALSE;
+	}
+
 	tmpbuf = erealloc(tmpbuf, retval + 1);
 	tmpbuf[retval] = '\0' ;
  

Actual result:
--------------
socket_read never returns, it gets looped in ext/sockets/sockets.c:885

Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2009-02-03 19:09 UTC] iliaa@php.net
There is no loop in the code, how would it get stuck unless you are 
doing while(socket_read()) ?
 [2009-02-04 14:50 UTC] patryk dot szczyglowski at gmail dot com
In php documentation:
"socket_read() returns the data as a string on success, or FALSE on error (including if the remote host has closed the connection)."

So I used:

while (($res = socket_read(...)) !== false) {
  // .. do something
}

To correct it without changes in PHP source code this loop should look:

while ($res != false) {
  // .. do something
}

but that's incorrect, because e.g. string '0' will match the condition and it is perfectly valid content.

Low level recv() function returns 0 only on disconnect, and while connected in blocking mode 0 is never returned to the application. Current PHP implementation is not compatible with recv(2) and PHP documentation.

So either you commit my patch or correct the documentation.

Thanks.
 [2009-02-11 15:35 UTC] patryk dot szczyglowski at gmail dot com
The information has been provided a week ago.
 [2009-02-11 15:44 UTC] felipe@php.net
Please try using this CVS snapshot:

  http://snaps.php.net/php5.2-latest.tar.gz
 
For Windows:

  http://windows.php.net/snapshots/


 [2009-02-19 01:00 UTC] php-bugs at lists dot php dot net
No feedback was provided for this bug for over a week, so it is
being suspended automatically. If you are able to provide the
information that was originally requested, please do so and change
the status of the bug back to "Open".
 [2009-03-26 16:36 UTC] patryk dot szczyglowski at gmail dot com
It seems that the patch fixes the problem. Thanks!
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Sat Dec 21 17:01:58 2024 UTC