|
php.net | support | documentation | report a bug | advanced search | search howto | statistics | random bug | login |
PatchesPull RequestsHistoryAllCommentsChangesGit/SVN commits
[2002-09-17 21:24 UTC] iliaa@php.net
[2002-10-08 21:42 UTC] sniper@php.net
|
|||||||||||||||||||||||||||||||||||||
Copyright © 2001-2025 The PHP GroupAll rights reserved. |
Last updated: Mon Oct 27 16:00:01 2025 UTC |
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 administrator@zinious.com 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-----