ID:               18351
 Updated by:       [EMAIL PROTECTED]
 Reported By:      [EMAIL PROTECTED]
-Status:           Open
+Status:           Feedback
 Bug Type:         Reproducible crash
 Operating System: Windows 2000 Server sp2, IIS 5.0
 PHP Version:      4.2.1
 New Comment:

Please try using this CVS snapshot:

  http://snaps.php.net/php4-latest.tar.gz
 
For Windows:
 
  http://snaps.php.net/win32/php4-win32-latest.zip




Previous Comments:
------------------------------------------------------------------------

[2002-07-15 09:05:35] [EMAIL PROTECTED]

Used the standard W32 build of PHP.EXE (I did not compile it).

Wrote a PHP script that acts as a relay server (client connects to me,
I connect to the destination server and act as a proxy/gateway to that
server for the client).

The destination server had closed the connection and my script
socket_select()'ed on it.  However, due to a bug in my script that
returned the wrong value, I proceeded to try and socket_read() from the
socket instead of closing the client connection and ending the script.

The result of a socket_read() after failing on a socket_select() caused
Windows 2000 Server s.p. 2 running IIS 5.0 to die immediately, forced a
warm boot of the machine (no GPF, just immediate warm boot).

I reproduced it 3 times, totalling 4 sucessful warm-boots before
finding my bug and fixing it.  I have not encountered the problem
since.

Incidently, my bug was returning "ZSC_LOSTCONNECTION" from a function
that polls the socket, but I was testing for "ZSC_CONNECTIONLOST"
instead.

Here is my full relay script, the fixed version (it's very simple to
"unfix it" and modify it to act as a normal relay instead of the
special service requests that I wrote in).

Hope this helps guys,
Peter Souza IV
CEO/administrator
[EMAIL PROTECTED]
Zinious Software corporation
www.zinious.com


-----script here-----
#!/usr/bin/php -q

<?php

function SocketCheck($socket_to_check)
{
        $readsocks = array($socket_to_check);

        $readsocks = array($socket_to_check);
        $num_changed_sockets = socket_select($readsocks, $writesocks = NULL,
$exceptsocks = NULL, 0);

        if ($num_changed_sockets > 0)
        {
                if (($indata = socket_read($socket_to_check, 1024)) !== false)
                {
                        if ($indata == "")
                                return "ZSC_LOSTCONNECTION";

                        return $indata;
                }
                else
                {
                        return "ZSC_LOSTCONNECTION";
                }
        }

        return "ZSC_NOCHANGE";
}

function DoServer( )
{
        error_reporting (E_ALL);
        set_time_limit (0);
        ob_implicit_flush ();


        $socket = socket_create( AF_INET , SOCK_STREAM , SOL_TCP);
        $player_socket = socket_create( AF_INET , SOCK_STREAM , SOL_TCP);
        $unused_socket = socket_create( AF_INET , SOCK_STREAM , SOL_TCP);

        $isbind = socket_bind($socket, "192.168.0.2", 23);

        if (!($isbind))
        {
                print "Error binding.\r\n";
                return 0;
        }

        print "--- Z.S.C. Relay Server: port 23 ---\r\n\r\n";

        socket_listen($socket);

        while (true)
        {
                $newsock = socket_accept($socket);
                if ($newsock)
                {
                        socket_getpeername($newsock, $host_from);
                        $host_from = $host_from." (".gethostbyaddr($host_from).")";
                        print "[CONNECTION] connection from $host_from\r\n";

                        $xdata = "";
                        for ($indata = "ZSC_NOCHANGE"; 
((!strstr($xdata,"\n"))&&($indata !=
"ZSC_LOSTCONNECTION")); $indata = SocketCheck($newsock))
                                if (($indata != "ZSC_LOSTCONNECTION") && ($indata !=
"ZSC_NOCHANGE"))
                                        $xdata .= $indata;

                        if ($indata == "ZSC_LOSTCONNECTION")
                        {
                                print "[CONNECTION] lost connection to 
$host_from\r\n";
                                socket_close($newsock);
                                continue;
                        }

                        $indata = $xdata;

                        if (strstr($indata, "master end relay"))
                        {
                                socket_write($newsock, "\r\n--- Z.S.C. Relay Server: 
shutdown
---\r\n");
                                print "\r\n--- Z.S.C. Relay Server: shutdown ---\r\n";
                                socket_close($newsock);
                                socket_close($socket);
                                return 0;
                        }

                        $szCharacterKey = substr($indata, 0, 32);
                        $szGameServiceCode = substr($indata, 33, 3);
                        $szGamePort = substr($indata, 37, 5);
                        $szGameHost = substr($indata, 43);
                        while (strstr($szGameHost, "\r") || strstr($szGameHost, "\n"))
                                $szGameHost = substr($szGameHost, 0, 
strlen($szGameHost) - 1);

                        print "[CONNECTION] KEY=$indata";

                        if (!strstr($indata, "/FE:"))
                        {
                                $xdata = "";
                                for ($indata = "ZSC_NOCHANGE"; 
((!strstr($xdata,"\n"))&&($indata !=
"ZSC_LOSTCONNECTION")); $indata = SocketCheck($newsock))
                                        if (($indata != "ZSC_LOSTCONNECTION") && 
($indata !=
"ZSC_NOCHANGE"))
                                                $xdata .= $indata;

                                if ($indata == "ZSC_LOSTCONNECTION")
                                {
                                        print "[CONNECTION] lost connection to 
$host_from\r\n";
                                        print "[CONNECTION] had received 
>$xdata<\r\n";
                                        socket_close($newsock);
                                        continue;
                                }

                                $indata = $xdata;
                        }

                        $text_out =
sprintf("%cGSBZSC-Relay%cGSA0000000000ZSC-Relay\r\n%cGSD\r\n%c---%c
%cWelcome to Z.S.C. relay server%c %c---%c\r\n%cGSP\r\n\r\n%c---%c
%cRelay will begin momentarily%c %c---%c\r\n\r\n", 28, 28, 28, 139,
160, 143, 160, 139, 160, 28, 139, 160, 143, 160, 139, 160);
                        socket_write($newsock, $text_out);

                        $xdata = "";
                        for ($indata = "ZSC_NOCHANGE"; 
((!strstr($xdata,"\n"))&&($indata !=
"ZSC_LOSTCONNECTION")); $indata = SocketCheck($newsock))
                                if (($indata != "ZSC_LOSTCONNECTION") && ($indata !=
"ZSC_NOCHANGE"))
                                        $xdata .= $indata;
                        if ($indata == "ZSC_LOSTCONNECTION")
                        {
                                print "[CONNECTION] lost connection to 
$host_from\r\n";
                                socket_close($newsock);
                                continue;
                        }
                        $indata = $xdata;



                        ///////////////
                        //  LOG IN!  //
                        ///////////////

                        $r_ip = $szGameHost;
                        $r_hostname = $r_ip; // gethostbyaddr($r_ip);
                        if ($r_hostname == $r_ip)
                        {
                                $r_ip = gethostbyname($r_hostname);
                                $r_hostname2 = gethostbyaddr($r_ip);
                        }
                        else
                                $r_hostname2 = $r_hostname;

                        print "[CONNECTION] conecting to $r_hostname ($r_ip /
$r_hostname2)...\r\n";

                        if (!socket_connect($player_socket, $r_ip, $szGamePort))
                        {
                                print "[CONNECTION] Error: could not establish 
connection\r\n";
                                $text_out = sprintf("\r\n\r\n%c---%c %cRelay session 
is over. 
Goodbye!%c %c---%c\r\n\r\n", 139, 160, 143, 160, 139, 160);
                                socket_write($newsock, $text_out);
                                print "[CONNECTION] closed connection with 
$host_from\r\n";
                                socket_close($newsock);
                        }
                        else
                        {
                                $text_out = sprintf("%s\n", $szCharacterKey);
                                socket_write($player_socket, $text_out);
                                socket_write($player_socket, "/FE:WIZARD /V:2.03 
/P:WIN32\n");

                                $shutdown_version = 0;
                                $remote_shutdown_version = 0;

                                for (;;)
                                {
                                        $indata = SocketCheck($player_socket);
                                        if ($indata != "ZSC_NOCHANGE")
                                        {
                                                if ($indata == "ZSC_LOSTCONNECTION")
                                                {
                                                        print "[CONNECTION] Connection 
to $r_hostname lost\r\n";
                                                        $remote_shutdown_version = 5;
                                                        break;
                                                }
                                                else
                                                {
                                                        if ($shutdown_version == 0)
                                                                socket_write($newsock, 
$indata);
        //                                              print "[RELAY-GAME] $indata";
                                                }
                                        }

                                        $indata = SocketCheck($newsock);
                                        if ($indata != "ZSC_NOCHANGE")
                                        {
                                                if ($indata == "ZSC_LOSTCONNECTION")
                                                {
                                                        print "[CONNECTION] Connection 
to $host_from lost\r\n";
                                                        $shutdown_version = 5;
                                                        break;
                                                }
                                                else
                                                {
                                                        if ($remote_shutdown_version 
== 0)
                                                                
socket_write($player_socket, $indata);
        //                                              print "[RELAY-PLAYER] 
$indata";
                                                }
                                        }
                                }

                                if ($remote_shutdown_version != 5)
                                {
                                        socket_write($player_socket, "QUIT\n");
                                        print "[CONNECTION] closing connection to 
$r_hostname...\r\n";
                                }
                                socket_close($player_socket);
                                $player_socket = socket_create( AF_INET , SOCK_STREAM 
, SOL_TCP);

                                if ($shutdown_version != 5)
                                {
                                        $text_out = sprintf("\r\n\r\n%c---%c %cRelay 
session is over. 
Goodbye!%c %c---%c\r\n\r\n", 139, 160, 143, 160, 139, 160);
                                        socket_write($newsock, $text_out);
                                        print "[CONNECTION] closing connection to 
$host_from...\r\n";
                                }
                                socket_close($newsock);
                        }
                }
                else
                {
                        print "[SYSERR] Error on call to accept().\r\n";
                        return 0;
                }
        }

        print "--- This line should never display ---\r\n";
}

DoServer( );

?>
-----script here-----


------------------------------------------------------------------------


-- 
Edit this bug report at http://bugs.php.net/?id=18351&edit=1

Reply via email to