php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #39803 fsockopen() bug
Submitted: 2006-12-12 01:10 UTC Modified: 2010-03-15 03:20 UTC
Votes:7
Avg. Score:4.6 ± 0.7
Reproduced:6 of 6 (100.0%)
Same Version:1 (16.7%)
Same OS:6 (100.0%)
From: marcelo at tpn dot com dot br Assigned:
Status: Not a bug Package: Sockets related
PHP Version: 4.4.9 OS: FreeBSD 6.2
Private report: No CVE-ID: None
 [2006-12-12 01:10 UTC] marcelo at tpn dot com dot br
Description:
------------
The function fsockopen() is always failing and returning -1.

I already tried with differents hostnames and IP address.

I'm using FreeBSD 5.3.

Reproduce code:
---------------
<?php
$fp = fsockopen("www.google.com", 80, $errno, $errstr, 30);
if (!$fp) {
   echo "$errstr ($errno)\n";
}
?> 

Expected result:
----------------
$fp should be TRUE...

Actual result:
--------------
But...

$fp is returning FALSE
$errno is returning 36
$errstr is returning "Operation now in progress"

Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2006-12-12 07:32 UTC] tony2001@php.net
Sorry, but your problem does not imply a bug in PHP itself.  For a
list of more appropriate places to ask for help using PHP, please
visit http://www.php.net/support.php as this bug system is not the
appropriate forum for asking support questions.  Due to the volume
of reports we can not explain in detail here why your report is not
a bug.  The support channels will be able to provide an explanation
for you.

Thank you for your interest in PHP.

Please consult your system administrator on how to disable the firewall.
 [2006-12-12 12:58 UTC] marcelo at tpn dot com dot br
Why socket_create() works and fsockopen() doesn't?

If there is some wrong outside PHP, why just fsockopen fails?
 [2006-12-12 14:10 UTC] marcelo at tpn dot com dot br
More details:

Using php-cgi, fsockopen works correctly.

The build date of the PHP (Apache Module) and PHP-CGI is the same.
 [2006-12-12 14:22 UTC] tony2001@php.net
Both CGI and Apache module share the same code for fsockopen(), so fsockopen() doesn't depend on the Server API used.
 [2006-12-12 15:22 UTC] marcelo at tpn dot com dot br
I don't understand.

If worked with CGI but not as an Apache Module, why you don't consider this a bug?

I believe that if the code is the same, should produce the same result, else there is a bug.
 [2006-12-12 15:42 UTC] tony2001@php.net
>I believe that if the code is the same, should produce the
> same result, else there is a bug.
No, it most likely means that it has nothing to do with this code and you're looking for a problem in wrong place.
Have you already disabled your firewall?
 [2006-12-12 16:19 UTC] marcelo at tpn dot com dot br
Yes, I've disabled my firewall. I'm sure that isn't a firewall problem.

The problem doesn't depend the hostname or IP address. I got the same error trying to connect to localhost, 127.0.0.1, 10.0.0.9 (internal network)

This also didn't work:

<?php
$fp = fsockopen("127.0.0.1", 80, $errno, $errstr, 30);
if (!$fp) {
   echo "$errstr ($errno)\n";
}
?> 

This also didn't work (connect to an internal server):

<?php
$fp = fsockopen("10.0.0.9", 80, $errno, $errstr, 30);
if (!$fp) {
   echo "$errstr ($errno)\n";
}
?> 

But I can use socket_connect without problems. Example:

<?
$sockHttp = socket_create(AF_INET, SOCK_STREAM, 0);
if (!$sockHttp) { die('socket_create() failed!'); }
      
$resSockHttp = socket_connect($sockHttp, "10.0.0.9", 80);
if (!$resSockHttp) { die('socket_connect() failed!'); }
?>

I also can use "fetch" utility to get data from these servers. I also wrote a PERL script, and it worked.

I also type in prompt "telnet 127.0.0.1 80", "telnet www.google.com 80", the connection was sucessfull.

Only while I'm using fsockopen I got errors, always error returns 36 and error string returns "Operation now in progress".
 [2006-12-12 16:32 UTC] tony2001@php.net
Does the fix from http://bugs.php.net/bug.php?id=38568 work for you?
 [2006-12-12 17:43 UTC] marcelo at tpn dot com dot br
I'm using PHP 4.4.4, not PHP 5.

network.c has two pieces that uses EINPROGRESS:

if ((n = connect(sockfd, addr, addrlen)) < 0) {
  if (errno != EINPROGRESS) {
    return -1;
  }
}

if (ret == -1 && error == EINPROGRESS) {
  error = 0;
  goto retry_again;
}

Where should I put "if (error == EINPROGRESS) error = 0;" ?
 [2006-12-13 10:09 UTC] tony2001@php.net
Please provide more information on how to reproduce it or an account on this machine.
 [2006-12-13 14:30 UTC] marcelo at tpn dot com dot br
Sent to tony2001@php.net.
 [2006-12-18 17:11 UTC] tony2001@php.net
I really doubt I can reproduce or investigate it with only an FTP account. When I said "account on this machine" I meant SSH access.
 [2007-04-05 13:39 UTC] marcelo at tpn dot com dot br
An user could fix this problem in PHP 5 adding 3 lines of code in main/network.c.

   if (!asynchronous) {
      /* back to blocking mode */
      RESTORE_SOCKET_BLOCKING_MODE(sockfd, orig_flags);
   }
/* Start changes */
   if (error == EINPROGRESS) {
       error = 0;
   }
/* End changes */
   if (error_code) {
      *error_code = error;
   }
   if (error && error_string) {
     *error_string = php_socket_strerror(error, NULL, 0);
     ret = -1;
   }
   return ret;

I try to modify PHP 4 but the code is a bit different. Can you help me to fix this problem?

The system is always returning EINPROGRESS.
 [2007-04-05 19:59 UTC] tony2001@php.net
>The system is always returning EINPROGRESS.
Why is that PHP problem?
Fix your system instead.
 [2007-05-03 18:29 UTC] marcelo at tpn dot com dot br
This is a PHP problem.

I have both CGI and Apache Module.

fsockopen() works on CGI mode, but doesn't in Apache Module.
 [2007-07-11 12:40 UTC] jani@php.net
So you're saying this problem exist in PHP 5.2.3 also?
If so, please set the version in this report to "5.2.3, 4.4.7" 
 [2009-07-14 05:05 UTC] marcelo at tpn dot com dot br
Now fsockopen crashes apache, but only when PHP is in apache module 
mode.
 [2009-07-23 22:48 UTC] jani@php.net
Apparently this isn't any PHP bug like already said many times.
 [2010-03-15 03:20 UTC] marcelo at tpn dot com dot br
Folks,

Regardless if it's a PHP problem or not, here is the SOLUTION:

fsockopen(), fopen() and other socket functions will not work in Apache with 
many virtualhosts.

You need to increase the file descriptor limits when compiling Apache and PHP 
(including its 
modules).

If you use FreeBSD, edit your /etc/make.conf and add:

EXTRA_CFLAGS="-DFD_SETSIZE=8192"

And rebuild Apache, PHP and its modules. I believe that 8192 is a number big 
enough, btw you can 
try a different number. I don't know how to do this using Linux, but should be 
similar.

There are MANY people with the same problem, and you are always saying this 
isn't a PHP bug, and 
the user should fix him system.

IMHO, if its not a bug, why have I to recompile it to make it works?

My suggestion: create a compile parameter to compile PHP and its modules with a 
bigger file 
descriptor limit (e.g. --big-fd-limit).

That's my two cents. ;-)

--
Marcelo Coelho
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Fri Apr 19 04:01:28 2024 UTC