php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #24756 fsockopen not detecting closed ports
Submitted: 2003-07-22 15:36 UTC Modified: 2003-11-17 18:16 UTC
Votes:3
Avg. Score:4.3 ± 0.9
Reproduced:2 of 2 (100.0%)
Same Version:1 (50.0%)
Same OS:2 (100.0%)
From: nalldrin at cs dot ucsd dot edu Assigned:
Status: No Feedback Package: Sockets related
PHP Version: 4.3.3RC2-dev OS: Windows XP Pro
Private report: No CVE-ID: None
View Add Comment Developer Edit
Welcome! If you don't have a Git account, you can't do anything here.
You can add a comment by following this link or if you reported this bug, you can edit this bug over here.
(description)
Block user comment
Status: Assign to:
Package:
Bug Type:
Summary:
From: nalldrin at cs dot ucsd dot edu
New email:
PHP Version: OS:

 

 [2003-07-22 15:36 UTC] nalldrin at cs dot ucsd dot edu
Description:
------------
I'm running PHP 4.3.2 on Windows XP and think I've found a bug in fsockopen().  When attempting to open a closed, non-blocked port, fsockopen() times out instead of returning immediately.  On linux, fsockopen() returns immediately instead of timing out.  I've tried the latest CVS version (php4-win32-STABLE-200307211230) and get the same problem.  Also perhaps relevant is the fact that fopen() seems to work correctly (ie, it does not time out like fsockopen).

Note: I think this is the same problem as bugs 23131, 21193, etc., but the problem does not seem to be fixed.

Here's some more info about the machine/php version I'm running:

System:
Microsoft Windows XP Professional Version 2002 Service Pack 1
Xeon 3.06GHz
512MB RAM

PHP:
<a href="http://louis.ucsd.edu/~nalldrin/phpbug/phpinfo.html>phpinfo</a>




Reproduce code:
---------------
<?php
set_time_limit(0);

$hostname = 'localhost'; //use any hostname:port combo that is closed, but not blocked
$port = 81;
$errno = null;
$error_str = null;

// FSOCKOPEN does not detect closed port and waits until timeout
echo microtime() . "\n";
$fp = fsockopen( $hostname, $port, $errno, $error_str, 10);
echo microtime();

echo "\nerrno: "; var_dump($errno);
echo "error_str: "; var_dump($error_str);
echo "retval: "; var_dump($fp);
if ($fp !== false) fclose($fp);


// FOPEN seems to correctly detect closed port and returns immediately
echo microtime() . "\n";
$fp2 = fopen ("http://$hostname:$port", "r");
echo microtime();

if ($fp2 !== false) fclose($fp2);

?>

Expected result:
----------------
The script should return immediately, saying the hostname/port is closed or something to that effect.

Actual result:
--------------
The fsockopen() call times out.

..........................................
0.98491200 1058903395
<br />
<b>Warning</b>:  fsockopen(): php_hostconnect: connect failed in <b>c:\Inetpub\wwwroot\phpbug\fsockopenbug.php</b> on line <b>11</b><br />
<br />
<b>Warning</b>:  fsockopen(): unable to connect to localhost:81 in <b>c:\Inetpub\wwwroot\phpbug\fsockopenbug.php</b> on line <b>11</b><br />
0.98788000 1058903405
errno: int(10060)
error_str: string(185) "A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond."
retval: bool(false)
0.98791200 1058903405
<br />
<b>Warning</b>:  fopen(): php_hostconnect: connect failed in <b>c:\Inetpub\wwwroot\phpbug\fsockopenbug.php</b> on line <b>22</b><br />
<br />
<b>Warning</b>:  fopen(http://localhost:81): failed to open stream: Bad file descriptor in <b>c:\Inetpub\wwwroot\phpbug\fsockopenbug.php</b> on line <b>22</b><br />
0.94688200 1058903406


Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2003-07-23 00:54 UTC] wez@php.net
The http:// wrapper internally calls the same connection routines as fsockopen, so I can't see how it could be behaving differently (error messages aside).

Can you explain what you mean by a closed-but-not-blocked port?
 [2003-07-23 01:06 UTC] nalldrin at cs dot ucsd dot edu
The problem isn't with fopen(); it's with fsockopen() which should be trying to create a raw tcp:// connection, not an http:// connection.  The point of comparing fsockopen with fopen was to show that somehow fopen can tell that the port is closed while fsockopen cannot (since they both need a tcp:// connection).

What I mean by "closed but not blocked" is a port that won't accept a tcp connection, but still sends out a reply to the connection attempt saying it's closed.  A blocked port would pretend it didn't see the connection attempt at all.  I'm probably muddling my terminology, but that's what I mean :).
 [2003-07-23 01:10 UTC] wez@php.net
*sigh* yes, fsockopen() creates a tcp connection.
the http:// wrapper uses those tcp connections to talk http.

So... you just mean a port that is not filtered but has no processes listening on it?

--Wez.
 [2003-07-23 14:10 UTC] nalldrin at cs dot ucsd dot edu
Yes, that's what I mean.

I wrote a more simple test case that tries to open port 9999 on www.php.net.  On linux the test returns immediately, as it should. But on win32, it spins until timeout.

..............................
<?php

// fsockopen spins on win32 on opening non-existant ports when it should fail
immediately.

$startTime = time();
fsockopen("www.php.net", 9999, $errno, $error_str, 10);
$totalTime = time() - $startTime;

if($totalTime >= 10) {
  print("Spun until timeout trying to open a closed port.  Huh?");
}

?>
..............................

Output:
..............................
Content-type: text/html
X-Powered-By: PHP/4.3.2

<br />
<b>Warning</b>:  fsockopen(): php_hostconnect: connect failed in <b>C:\cygwin\home\Neil Alldrin\test.php</b> on line <b>7</b><br />
<br />
<b>Warning</b>:  fsockopen(): unable to connect to www.php.net:9999 in <b>C:\cygwin\home\Neil Alldrin\test.php</b> on line <b>7</b><br />
Spun until timeout trying to open a closed port.  Huh?
 [2003-07-24 09:08 UTC] iliaa@php.net
On WinXP using latest stable snapshot from July 24th does infact stall and wait for the timeout to occur.
<?php
fsockopen("www.php.net", 9999, $errno, $err_str, 10);
?>.
However, this does not appear to happen with PHP5 snapshot.
 [2003-11-17 18:16 UTC] sniper@php.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-2022 The PHP Group
All rights reserved.
Last updated: Mon Sep 26 22:05:54 2022 UTC