--- a/functions.php Wed Oct 08 21:56:21 2008 -0400
+++ b/functions.php Sun Nov 23 23:43:52 2008 -0500
@@ -295,7 +295,7 @@
require(GREY_ROOT . '/config.php');
}
- foreach ( array('public', 'allowcontrol', 'theme', 'allow_fork', 'use_auth', 'auth_data', 'configpass') as $var )
+ foreach ( array('public', 'enable_ipv4', 'enable_ipv6', 'allowcontrol', 'theme', 'allow_fork', 'use_auth', 'auth_data', 'configpass') as $var )
{
if ( isset($$var) )
{
--- a/webserver.php Wed Oct 08 21:56:21 2008 -0400
+++ b/webserver.php Sun Nov 23 23:43:52 2008 -0500
@@ -286,7 +286,37 @@
$class = 'Socket_' . HTTPD_SOCKET_LAYER;
$this->server = new $class();
- $this->server->tcp_listen($address, $port);
+ if ( is_array($address) )
+ {
+ foreach ( $address as $a )
+ {
+ if ( is_array($port) )
+ {
+ foreach ( $port as $p )
+ {
+ $this->server->tcp_listen($a, $p);
+ }
+ }
+ else
+ {
+ $this->server->tcp_listen($a, $port);
+ }
+ }
+ }
+ else
+ {
+ if ( is_array($port) )
+ {
+ foreach ( $port as $p )
+ {
+ $this->server->tcp_listen($address, $p);
+ }
+ }
+ else
+ {
+ $this->server->tcp_listen($address, $port);
+ }
+ }
// if running as root and we made it here, switch credentials
if ( $socket_do_root )
@@ -1849,7 +1879,7 @@
class Socket_Raw
{
- var $sock;
+ var $sock = array();
var $socket_initted = false;
function tcp_listen($address, $port)
@@ -1860,14 +1890,17 @@
burnout('System does not support socket functions. Please rebuild your PHP or install an appropriate extension.');
}
- $this->sock = @socket_create(AF_INET, SOCK_STREAM, getprotobyname('tcp'));
- if ( !$this->sock )
+ $sockid = count($this->sock);
+
+ $socktype = ( strstr($address, ':') ) ? AF_INET6 : AF_INET;
+ $this->sock[$sockid] = @socket_create($socktype, SOCK_STREAM, getprotobyname('tcp'));
+ if ( !$this->sock[$sockid] )
throw new Exception('Could not create socket');
- $result = @socket_bind($this->sock, $address, $port);
+ $result = @socket_bind($this->sock[$sockid], $address, $port);
if ( !$result )
throw new Exception("Could not bind to $address:$port");
$this->socket_initted = true;
- $result = @socket_listen($this->sock, SOMAXCONN);
+ $result = @socket_listen($this->sock[$sockid], SOMAXCONN);
if ( !$result )
throw new Exception("Could not listen for connections $address:$port");
@@ -1879,31 +1912,49 @@
if ( $this->socket_initted )
{
// http://us3.php.net/manual/en/function.socket-bind.php
- if ( !@socket_set_option($this->sock, SOL_SOCKET, SO_REUSEADDR, 1) )
+ if ( is_array($this->sock) )
{
- echo socket_strerror(socket_last_error($this->sock)) . "\n";
+ foreach ( $this->sock as $sock )
+ {
+ if ( !@socket_set_option($sock, SOL_SOCKET, SO_REUSEADDR, 1) )
+ {
+ echo socket_strerror(socket_last_error($sock)) . "\n";
+ }
+ @socket_shutdown($sock, 2);
+ @socket_close($sock);
+ }
}
- @socket_shutdown($this->sock, 2);
- @socket_close($this->sock);
+ else
+ {
+ if ( !@socket_set_option($this->sock, SOL_SOCKET, SO_REUSEADDR, 1) )
+ {
+ echo socket_strerror(socket_last_error($this->sock)) . "\n";
+ }
+ @socket_shutdown($this->sock, 2);
+ @socket_close($this->sock);
+ }
}
}
function accept()
{
$remote = false;
- $timeout = 5;
- switch(@socket_select($r = array($this->sock), $w = array($this->sock), $e = array($this->sock), $timeout)) {
- case 2:
- return false;
- case 1:
- $remote = @socket_accept($this->sock);
- $return = new Socket_Raw();
- $return->sock = $remote;
- $return->socket_initted = true;
- return $return;
- break;
- case 0:
- return false;
+ foreach ( $this->sock as $sock )
+ {
+ $timeout = 200000;
+ switch(@socket_select($r = array($sock), $w = array($sock), $e = array($sock), 0, $timeout)) {
+ case 2:
+ return false;
+ case 1:
+ $remote = @socket_accept($sock);
+ $return = new Socket_Raw();
+ $return->sock = $remote;
+ $return->socket_initted = true;
+ return $return;
+ break;
+ case 0:
+ continue;
+ }
}
}
@@ -1961,7 +2012,7 @@
class Socket_Stream
{
- var $sock;
+ var $sock = array();
var $socket_initted = false;
function tcp_listen($address, $port)
@@ -1972,9 +2023,19 @@
burnout('System does not support stream functions. Please rebuild your PHP or install an appropriate extension.');
}
- $this->sock = @stream_socket_server("tcp://$address:$port", $errno, $errstr);
- if ( !$this->sock )
+ if ( strstr($address, ':') )
+ {
+ // ipv6 address (probably)
+ $address = "[$address]";
+ }
+
+ $sockid = count($this->sock);
+
+ $this->sock[$sockid] = @stream_socket_server("tcp://$address:$port", $errno, $errstr);
+ if ( !$this->sock[$sockid] )
+ {
throw new Exception("Could not create the socket: error $errno: $errstr");
+ }
}
function destroy()
@@ -1982,13 +2043,30 @@
if ( $this->socket_initted )
{
// PHP >= 5.2.1
- if ( function_exists('stream_socket_shutdown') )
+ if ( is_array($this->sock) )
{
- @stream_socket_shutdown($this->sock, STREAM_SHUT_RDWR);
+ foreach ( $this->sock as $sock )
+ {
+ if ( function_exists('stream_socket_shutdown') )
+ {
+ @stream_socket_shutdown($sock, STREAM_SHUT_RDWR);
+ }
+ while ( !@fclose($sock) )
+ {
+ usleep(100000);
+ }
+ }
}
- while ( !@fclose($this->sock) )
+ else
{
- usleep(100000);
+ if ( function_exists('stream_socket_shutdown') )
+ {
+ @stream_socket_shutdown($this->sock, STREAM_SHUT_RDWR);
+ }
+ while ( !@fclose($this->sock) )
+ {
+ usleep(100000);
+ }
}
}
}
@@ -1996,18 +2074,21 @@
function accept()
{
// the goal of a custom accept() with *_select() is to tick every 200ms to allow signals.
- stream_set_blocking($this->sock, 1);
- $timeout = 5;
- $selection = @stream_select($r = array($this->sock), $w = array($this->sock), $e = array($this->sock), $timeout);
- if ( !$selection )
+ foreach ( $this->sock as $sock )
{
- return false;
+ stream_set_blocking($sock, 1);
+ $timeout = 200000;
+ $selection = @stream_select($r = array($sock), $w = array($sock), $e = array($sock), 0, $timeout);
+ if ( !$selection )
+ {
+ return false;
+ }
+ $remote = stream_socket_accept($sock);
+ $return = new Socket_Stream();
+ $return->sock = $remote;
+ $return->socket_initted = true;
+ return $return;
}
- $remote = stream_socket_accept($this->sock);
- $return = new Socket_Stream();
- $return->sock = $remote;
- $return->socket_initted = true;
- return $return;
}
function soft_shutdown()