From 3702d6e3f543a30966f23ef978dfdb9a5cbdebbe Mon Sep 17 00:00:00 2001 From: =?utf8?q?Roland=20H=C3=A4der?= Date: Sat, 22 May 2010 16:04:05 +0000 Subject: [PATCH] Many classes/interfaces added/continued: - New 'tag' SocketTag added - New classes for connection helper added - TCP connection helper is maybe useable - UDP connection helper is not yet finished - New class for self connections added - HubTools added which should provide a set of static methods - SocketRegistry from core project added - Continued (but maybe not-working) announcement --- .gitattributes | 7 + application/hub/config.php | 18 ++ .../discovery/class_DiscoverableSocket.php | 1 + .../hub/interfaces/nodes/class_NodeHelper.php | 9 + .../interfaces/package/class_Deliverable.php | 30 ++- .../pool/peer/class_PoolablePeer.php | 2 +- application/hub/interfaces/socket/.htaccess | 1 + .../hub/interfaces/socket/class_SocketTag.php | 35 +++ application/hub/main/class_BaseHubSystem.php | 24 ++ .../socket/class_PackageSocketDiscovery.php | 72 ++++-- .../tcp/class_TcpNetworkPackageHandler.php | 2 +- .../hub/main/helper/connection/.htaccess | 1 + .../connection/class_BaseConnectionHelper.php | 172 +++++++++++++ .../hub/main/helper/connection/tcp/.htaccess | 1 + .../tcp/class_TcpConnectionHelper.php | 138 ++++++++++ .../hub/main/helper/connection/udp/.htaccess | 1 + .../udp/class_UdpConnectionHelper.php | 51 ++++ application/hub/main/helper/hub/class_ | 6 - .../main/helper/hub/class_BaseHubHelper.php | 28 +-- .../hub/main/helper/hub/connection/.htaccess | 1 + .../connection/class_HubConnectionHelper.php | 56 +++++ .../connection/class_HubSelfConnectHelper.php | 60 +++++ .../hub/main/listener/class_BaseListener.php | 26 +- .../listener/class_BaseListenerDecorator.php | 9 + .../hub/main/nodes/class_BaseHubNode.php | 31 ++- .../hub/main/package/class_NetworkPackage.php | 81 +++++- .../main/pools/peer/class_DefaultPeerPool.php | 28 ++- .../hub/main/registry/socket/.htaccess | 1 + .../registry/socket/class_SocketRegistry.php | 237 ++++++++++++++++++ .../tasks/hub/class_HubSelfConnectTask.php | 3 +- .../class_NetworkPackageWriterTask.php | 5 +- application/hub/main/tools/.htaccess | 1 + application/hub/main/tools/class_HubTools.php | 56 +++++ 33 files changed, 1101 insertions(+), 93 deletions(-) create mode 100644 application/hub/interfaces/socket/.htaccess create mode 100644 application/hub/interfaces/socket/class_SocketTag.php create mode 100644 application/hub/main/helper/connection/.htaccess create mode 100644 application/hub/main/helper/connection/class_BaseConnectionHelper.php create mode 100644 application/hub/main/helper/connection/tcp/.htaccess create mode 100644 application/hub/main/helper/connection/tcp/class_TcpConnectionHelper.php create mode 100644 application/hub/main/helper/connection/udp/.htaccess create mode 100644 application/hub/main/helper/connection/udp/class_UdpConnectionHelper.php create mode 100644 application/hub/main/helper/hub/connection/.htaccess create mode 100644 application/hub/main/helper/hub/connection/class_HubConnectionHelper.php create mode 100644 application/hub/main/helper/hub/connection/class_HubSelfConnectHelper.php create mode 100644 application/hub/main/registry/socket/.htaccess create mode 100644 application/hub/main/registry/socket/class_SocketRegistry.php create mode 100644 application/hub/main/tools/.htaccess create mode 100644 application/hub/main/tools/class_HubTools.php diff --git a/.gitattributes b/.gitattributes index 3bd89630d..e1c935d89 100644 --- a/.gitattributes +++ b/.gitattributes @@ -49,6 +49,7 @@ application/hub/interfaces/query/.htaccess -text application/hub/interfaces/query/class_Queryable.php -text application/hub/interfaces/queues/.htaccess -text application/hub/interfaces/queues/class_Queueable.php -text +application/hub/interfaces/socket/.htaccess -text application/hub/interfaces/states/.htaccess -text application/hub/interfaces/states/class_ -text application/hub/interfaces/states/class_Stateable.php -text @@ -165,11 +166,15 @@ application/hub/main/handler/network/udp/class_UdpNetworkPackageHandler.php -tex application/hub/main/handler/tasks/.htaccess -text application/hub/main/handler/tasks/class_TaskHandler.php -text application/hub/main/helper/.htaccess -text +application/hub/main/helper/connection/.htaccess -text +application/hub/main/helper/connection/tcp/.htaccess -text +application/hub/main/helper/connection/udp/.htaccess -text application/hub/main/helper/hub/.htaccess -text application/hub/main/helper/hub/announcement/.htaccess -text application/hub/main/helper/hub/announcement/class_HubDescriptorHelper.php -text application/hub/main/helper/hub/class_ -text application/hub/main/helper/hub/class_BaseHubHelper.php -text +application/hub/main/helper/hub/connection/.htaccess -text application/hub/main/iterator/.htaccess -text application/hub/main/iterator/class_ -text application/hub/main/iterator/class_BaseIterator.php -text @@ -250,6 +255,7 @@ application/hub/main/queues/peer/.htaccess -text application/hub/main/queues/peer/class_LocalPeerQueue.php -text application/hub/main/registry/.htaccess -text application/hub/main/registry/objects/.htaccess -text +application/hub/main/registry/socket/.htaccess -text application/hub/main/resolver/.htaccess -text application/hub/main/resolver/command/.htaccess -text application/hub/main/resolver/command/console/.htaccess -text @@ -300,6 +306,7 @@ application/hub/main/template/.htaccess -text application/hub/main/template/announcement/.htaccess -text application/hub/main/template/announcement/class_AnnouncementTemplateEngine.php -text application/hub/main/template/objects/.htaccess -text +application/hub/main/tools/.htaccess -text application/hub/main/visitor/.htaccess -text application/hub/main/visitor/class_ -text application/hub/main/visitor/class_BaseVisitor.php -text diff --git a/application/hub/config.php b/application/hub/config.php index 1f4741eea..509c9798b 100644 --- a/application/hub/config.php +++ b/application/hub/config.php @@ -114,6 +114,9 @@ $cfg->setConfigEntry('list_group_class', 'ListGroupList'); // CFG: HUB-ANNOUNCEMENT-HELPER-CLASS $cfg->setConfigEntry('hub_announcement_helper_class', 'HubDescriptorHelper'); +// CFG: HUB-SELF-CONNECT-HELPER-CLASS +$cfg->setConfigEntry('hub_self_connect_helper_class', 'HubSelfConnectHelper'); + // CFG: DEFAULT-CONSOLE-COMMAND $cfg->setConfigEntry('default_console_command', 'main'); @@ -222,6 +225,9 @@ $cfg->setConfigEntry('stacker_undeclared_max_size', 10000); // CFG: STACKER-DECLARED-MAX-SIZE $cfg->setConfigEntry('stacker_declared_max_size', 1000); +// CFG: STACKER-OUTGOING-MAX-SIZE +$cfg->setConfigEntry('stacker_outgoing_max_size', 100); + // CFG: STACKER-OBJECT-REGISTRY-MAX-SIZE $cfg->setConfigEntry('stacker_object_registry_max_size', 100); @@ -384,5 +390,17 @@ $cfg->setConfigEntry('recipient_list_class', 'RecipientList'); // CFG: PACKAGE-TAGS-CLASS $cfg->setConfigEntry('package_tags_class', 'PackageTags'); +// CFG: TCP-CONNECTION-CLASS +$cfg->setConfigEntry('tcp_connection_class', 'TcpConnectionHelper'); + +// CFG: UDP-CONNECTION-CLASS +$cfg->setConfigEntry('udp_connection_class', 'UdpConnectionHelper'); + +// CFG: TCP-BUFFER-LENGTH +$cfg->setConfigEntry('tcp_buffer_length', 1024); + +// CFG: UDP-BUFFER-LENGTH +$cfg->setConfigEntry('udp_buffer_length', 1024); + // [EOF] ?> diff --git a/application/hub/interfaces/discovery/class_DiscoverableSocket.php b/application/hub/interfaces/discovery/class_DiscoverableSocket.php index 889f4aeb0..3c589c9c4 100644 --- a/application/hub/interfaces/discovery/class_DiscoverableSocket.php +++ b/application/hub/interfaces/discovery/class_DiscoverableSocket.php @@ -27,6 +27,7 @@ interface DiscoverableSocket extends FrameworkInterface { * matching socket resource. * * @param $packageData Raw package data array + * @param $packageInstance A Deliverable instance * @return $socketResource A valid socket resource */ function discoverSocket (array $packageData); diff --git a/application/hub/interfaces/nodes/class_NodeHelper.php b/application/hub/interfaces/nodes/class_NodeHelper.php index 5ca4ba82b..6b9f7b913 100644 --- a/application/hub/interfaces/nodes/class_NodeHelper.php +++ b/application/hub/interfaces/nodes/class_NodeHelper.php @@ -105,6 +105,15 @@ interface NodeHelper extends FrameworkInterface { * @throws HubAlreadyAnnouncedException If this hub is already announced */ function announceSelfToUpperNodes (Taskable $taskInstance); + + /** + * Does a self-connect attempt on the public IP address. This should make + * it sure, we are reachable from outside world. + * + * @param $taskInstance The task instance running this announcement + * @return void + */ + function doSelfConnection (Taskable $taskInstance); } // [EOF] diff --git a/application/hub/interfaces/package/class_Deliverable.php b/application/hub/interfaces/package/class_Deliverable.php index c3f75ae57..cdf483346 100644 --- a/application/hub/interfaces/package/class_Deliverable.php +++ b/application/hub/interfaces/package/class_Deliverable.php @@ -24,7 +24,7 @@ interface Deliverable extends FrameworkInterface { /** * "Enqueues" raw content into this delivery class by reading the raw content - * from given template instance. + * from given template instance and pushing it on the 'undeclared' stack. * * @param $helperInstance A BaseHubHelper instance * @return void @@ -38,6 +38,20 @@ interface Deliverable extends FrameworkInterface { */ function isPackageEnqueued (); + /** + * Checks wether a package has been declared + * + * @return $isDeclared Wether a package is declared + */ + function isPackageDeclared (); + + /** + * Checks wether a package should be sent out + * + * @return $isWaitingDelivery Wether a package is waiting for delivery + */ + function isPackageWaitingDelivery (); + /** * Delivers an enqueued package to the stated destination. If a non-session * id is provided, recipient resolver is being asked (and instanced once). @@ -50,13 +64,6 @@ interface Deliverable extends FrameworkInterface { */ function declareEnqueuedPackage (); - /** - * Checks wether a package has been declared - * - * @return $isDeclared Wether a package is declared - */ - function isPackageDeclared (); - /** * Delivers the next declared package. Only one package per time will be sent * because this may take time and slows down the whole delivery @@ -65,6 +72,13 @@ interface Deliverable extends FrameworkInterface { * @return void */ function deliverDeclaredPackage (); + + /** + * Sends waiting packages out for delivery + * + * @return void + */ + function sentWaitingPackage (); } // [EOF] diff --git a/application/hub/interfaces/pool/peer/class_PoolablePeer.php b/application/hub/interfaces/pool/peer/class_PoolablePeer.php index 6d91da516..356dde94b 100644 --- a/application/hub/interfaces/pool/peer/class_PoolablePeer.php +++ b/application/hub/interfaces/pool/peer/class_PoolablePeer.php @@ -21,7 +21,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ -interface PoolablePeer extends Poolable { +interface PoolablePeer extends Poolable, SocketTag { /** * Adds a socket resource to the peer pool * diff --git a/application/hub/interfaces/socket/.htaccess b/application/hub/interfaces/socket/.htaccess new file mode 100644 index 000000000..3a4288278 --- /dev/null +++ b/application/hub/interfaces/socket/.htaccess @@ -0,0 +1 @@ +Deny from all diff --git a/application/hub/interfaces/socket/class_SocketTag.php b/application/hub/interfaces/socket/class_SocketTag.php new file mode 100644 index 000000000..5565d4eb6 --- /dev/null +++ b/application/hub/interfaces/socket/class_SocketTag.php @@ -0,0 +1,35 @@ + + * @version 0.0.0 + * @copyright Copyright (c) 2007, 2008 Roland Haeder, 2009, 2010 Hub Developer Team + * @license GNU GPL 3.0 or any newer version + * @link http://www.ship-simu.org + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +interface SocketTag extends FrameworkInterface { + /** + * "Getter" for a valid socket resource from given packae data. + * + * @param $packageData Raw package data + * @return $socketResource Socket resource + */ + function getSocketFromPackageData (array $packageData); +} + +// [EOF] +?> diff --git a/application/hub/main/class_BaseHubSystem.php b/application/hub/main/class_BaseHubSystem.php index 6a4608d53..293da4cc0 100644 --- a/application/hub/main/class_BaseHubSystem.php +++ b/application/hub/main/class_BaseHubSystem.php @@ -32,6 +32,11 @@ class BaseHubSystem extends BaseFrameworkSystem { */ private $listenerInstance = null; + /** + * A network package handler instance + */ + private $packageInstance = null; + /** * Protected constructor * @@ -80,6 +85,25 @@ class BaseHubSystem extends BaseFrameworkSystem { public final function getNodeInstance () { return $this->nodeInstance; } + + /** + * Setter for network package handler instance + * + * @param $packageInstance The network package handler instance we shall set + * @return void + */ + protected final function setPackageInstance (Networkable $packageInstance) { + $this->packageInstance = $packageInstance; + } + + /** + * Getter for network package handler instance + * + * @return $packageInstance The network package handler instance we shall set + */ + protected final function getPackageInstance () { + return $this->packageInstance; + } } // [EOF] diff --git a/application/hub/main/discovery/socket/class_PackageSocketDiscovery.php b/application/hub/main/discovery/socket/class_PackageSocketDiscovery.php index 2435a4d67..ea38e9c24 100644 --- a/application/hub/main/discovery/socket/class_PackageSocketDiscovery.php +++ b/application/hub/main/discovery/socket/class_PackageSocketDiscovery.php @@ -48,6 +48,40 @@ class PackageSocketDiscovery extends BaseDiscovery implements DiscoverableSocket return $discoveryInstance; } + /** + * Tries to dicover the right listener instance + * + * @param $protocolName Protocol name + * @param $packageData Raw package data + * @return $listenerInstance An instance of a Listenable instance or null + */ + public function discoverListenerInstance ($protocolName, array $packageData) { + /* + * Get the listener pool instance, we need to lookup the matching + * listener->poolInstance chain there. + */ + $poolInstance = Registry::getRegistry()->getInstance('node')->getListenerPoolInstance(); + + // Init listener instance + $listenerInstance = null; + + /* + * Now we need to choose again. It is wether we are speaking with a hub + * or with a client. So just handle it over to all listeners in this + * pool. + */ + foreach ($poolInstance->getPoolEntriesInstance()->getArrayFromGroup($protocolName) as $listenerInstance) { + // Does the listener want that package? + if ($listenerInstance->ifListenerAcceptsPackageData($packageData)) { + // This listener likes our package data, so abort here + break; + } // END - if + } // END - foreach + + // Return it + return $listenerInstance; + } + /** * Tries to discover the right socket for given package data and returns a * matching socket resource for that protocol. @@ -69,29 +103,29 @@ class PackageSocketDiscovery extends BaseDiscovery implements DiscoverableSocket */ $protocolName = $tagsInstance->chooseProtocolFromPackageData($packageData); - /* - * Get the listener pool instance, we need to lookup the matching - * listener->poolInstance chain there. - */ - $poolInstance = Registry::getRegistry()->getInstance('node')->getListenerPoolInstance(); + // Get the listener instance + $listenerInstance = $this->discoverListenerInstance($protocolName, $packageData); - // So get the pool entries list first - $poolEntriesInstance = $poolInstance->getPoolEntriesInstance(); + // If there is no listener who wants to have that package, we simply drop it here + if (is_null($listenerInstance)) { + // @TODO We may need some locking here + // Abort with no resource + return false; + } // END - if /* - * Now we need to choose again. It is wether we are speaking with a hub - * or with a client. So just handle it over to all listeners in that - * pool. + * Now we have the listener instance, we can determine the right + * resource to continue. The first step is to get the attached pool + * instance and pass over the whole package data to get the right + * socket. */ - foreach ($poolEntriesInstance->getArrayFromGroup($protocolName) as $listenerInstance) { - // Does the listener want that package? - if ($listenerInstance->ifListenerAcceptsPackageData($packageData)) { - // This listener likes our package data! - die(print_r($listenerInstance, true)); - break; - } // END - if - } // END - foreach - die(); + $socketResource = $listenerInstance->getPoolInstance()->getSocketFromPackageData($packageData); + + // Is it false, the recipient isn't known to us and we have no connection to it + if (!is_resource($socketResource)) { + // Create a new socket resource + $socketResource = HubConnectionHelper::getSocketFromPackageData($packageData, $protocolName); + } // END - if // And return it return $socketResource; diff --git a/application/hub/main/handler/network/tcp/class_TcpNetworkPackageHandler.php b/application/hub/main/handler/network/tcp/class_TcpNetworkPackageHandler.php index 0d91d1024..7e1033f12 100644 --- a/application/hub/main/handler/network/tcp/class_TcpNetworkPackageHandler.php +++ b/application/hub/main/handler/network/tcp/class_TcpNetworkPackageHandler.php @@ -74,7 +74,7 @@ class TcpNetworkPackageHandler extends BaseNetworkPackageHandler implements Netw $this->debugOutput('HANDLER: Handling TCP package from peer ' . $resource); // Read the raw data from socket - $rawData = socket_read($resource, 1500, PHP_NORMAL_READ); + $rawData = socket_read($resource, $this->getConfigInstance()->getConfigEntry('tcp_buffer_length'), PHP_NORMAL_READ); // Is it valid? if (($rawData === false) || (socket_last_error($resource) > 0)) { diff --git a/application/hub/main/helper/connection/.htaccess b/application/hub/main/helper/connection/.htaccess new file mode 100644 index 000000000..3a4288278 --- /dev/null +++ b/application/hub/main/helper/connection/.htaccess @@ -0,0 +1 @@ +Deny from all diff --git a/application/hub/main/helper/connection/class_BaseConnectionHelper.php b/application/hub/main/helper/connection/class_BaseConnectionHelper.php new file mode 100644 index 000000000..99f1221f1 --- /dev/null +++ b/application/hub/main/helper/connection/class_BaseConnectionHelper.php @@ -0,0 +1,172 @@ + + * @version 0.0.0 + * @copyright Copyright (c) 2007, 2008 Roland Haeder, 2009, 2010 Hub Developer Team + * @license GNU GPL 3.0 or any newer version + * @link http://www.ship-simu.org + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +class BaseConnectionHelper extends BaseHubHelper implements Registerable, ProtocolHandler { + /** + * Protocol used + */ + private $protocol = 'invalid'; + + /** + * Port number used + */ + private $port = 0; + + /** + * (IP) Adress used + */ + private $address = 0; + + /** + * Sent data in bytes + */ + private $sentData = 0; + + /** + * Offset + */ + private $offset = 0; + + /** + * Protected constructor + * + * @param $className Name of the class + * @return void + */ + protected function __construct ($className) { + // Call parent constructor + parent::__construct($className); + + // Register this connection helper + Registry::getRegistry()->addInstance('connection', $this); + } + + /** + * Getter for port number to satify ProtocolHandler + * + * @return $port The port number + */ + public final function getPort () { + return $this->port; + } + + /** + * Setter for port number to satify ProtocolHandler + * + * @param $port The port number + * @return void + */ + protected final function setPort ($port) { + $this->port = $port; + } + + /** + * Getter for protocol + * + * @return $protocol Used protocol + */ + public final function getProtocol () { + return $this->protocol; + } + + /** + * Setter for protocol + * + * @param $protocol Used protocol + * @return void + */ + protected final function setProtocol ($protocol) { + $this->protocol = $protocol; + } + + /** + * Getter for IP address + * + * @return $address The IP address + */ + public final function getAddress () { + return $this->address; + } + + /** + * Setter for IP address + * + * @param $address The IP address + * @return void + */ + protected final function setAddress ($address) { + $this->address = $address; + } + + /** + * Sends raw package data to the recipient + * + * @param $packageData Raw package data + * @return void + *@ throws InvalidSocketException If we got a problem with this socket + */ + public function sendRawPackageData (array $packageData) { + // We need to "package" all data. This is done by a implode() + $rawData = implode(NetworkPackage::PACKAGE_DATA_SEPERATOR, $packageData); + + // Get socket resource + $socketResource = $this->getSocketResource(); + + // And deliver it + $numBytes = @socket_write($socketResource, $rawData, $this->getConfigInstance()->getConfigEntry($this->getProtocol() . '_buffer_length') - $this->offset); + + // If there was an error, we don't continue here + if ($numBytes === false) { + // Get socket error code for verification + $socketError = socket_last_error($socketResource); + + // Get error message + $errorMessage = socket_strerror($socketError); + + // Shutdown this socket + $this->shutdownSocket($socketResource); + + // And throw it + throw new InvalidSocketException(array($this, gettype($socketResource), $socketError, $errorMessage), BaseListener::EXCEPTION_INVALID_SOCKET); + } // END - if + + // How much has been sent? + die('num='.$numBytes."\n"); + } + + /** + * Getter for real class name + * + * @return $class Name of this class + */ + public function __toString () { + // Class name representation + $class = $this->getAddress() . ':' . $this->getPort() . ':' . parent::__toString(); + + // Return it + return $class; + } +} + +// [EOF] +?> diff --git a/application/hub/main/helper/connection/tcp/.htaccess b/application/hub/main/helper/connection/tcp/.htaccess new file mode 100644 index 000000000..3a4288278 --- /dev/null +++ b/application/hub/main/helper/connection/tcp/.htaccess @@ -0,0 +1 @@ +Deny from all diff --git a/application/hub/main/helper/connection/tcp/class_TcpConnectionHelper.php b/application/hub/main/helper/connection/tcp/class_TcpConnectionHelper.php new file mode 100644 index 000000000..b8c1295dc --- /dev/null +++ b/application/hub/main/helper/connection/tcp/class_TcpConnectionHelper.php @@ -0,0 +1,138 @@ + + * @version 0.0.0 + * @copyright Copyright (c) 2007, 2008 Roland Haeder, 2009, 2010 Core Developer Team + * @license GNU GPL 3.0 or any newer version + * @link http://www.ship-simu.org + * @todo Find an interface for hub helper + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +class TcpConnectionHelper extends BaseConnectionHelper { + /** + * Protected constructor + * + * @return void + */ + protected function __construct () { + // Call parent constructor + parent::__construct(__CLASS__); + + // Set protocol + $this->setProtocol('tcp'); + } + + /** + * Creates a socket resource ("connection") for given recipient in package data + * + * @param $packageData Raw package data + * @return $socketResource Socket resource + * @throws InvalidSocketException If the socket is invalid + */ + public static function createConnectionFromPackageData (array $packageData) { + // Create an instance + $helperInstance = new TcpConnectionHelper(); + + // Create a socket instance + $socketResource = socket_create(AF_INET, SOCK_STREAM, SOL_TCP); + + // Is the socket resource valid? + if (!is_resource($socketResource)) { + // Something bad happened + throw new InvalidSocketException(array($helperInstance, gettype($socketResource), 0, 'invalid'), BaseListener::EXCEPTION_INVALID_SOCKET); + } // END - if + + // Get socket error code for verification + $socketError = socket_last_error($socketResource); + + // Check if there was an error else + if ($socketError > 0) { + // Then throw again + throw new InvalidSocketException(array($helperInstance, gettype($socketResource), $socketError, socket_strerror($socketError)), BaseListener::EXCEPTION_INVALID_SOCKET); + } // END - if + + // Set the option to reuse the port + if (!socket_set_option($socketResource, SOL_SOCKET, SO_REUSEADDR, 1)) { + // Get socket error code for verification + $socketError = socket_last_error($socketResource); + + // Get error message + $errorMessage = socket_strerror($socketError); + + // Shutdown this socket + $helperInstance->shutdownSocket($socketResource); + + // And throw again + throw new InvalidSocketException(array($helperInstance, gettype($socketResource), $socketError, $errorMessage), BaseListener::EXCEPTION_INVALID_SOCKET); + } // END - if + + // Now, we want non-blocking mode + if (!socket_set_nonblock($socketResource)) { + // Get socket error code for verification + $socketError = socket_last_error($socketResource); + + // Get error message + $errorMessage = socket_strerror($socketError); + + // Shutdown this socket + $helperInstance->shutdownSocket($socketResource); + + // And throw again + throw new InvalidSocketException(array($helperInstance, gettype($socketResource), $socketError, $errorMessage), BaseListener::EXCEPTION_INVALID_SOCKET); + } // END - if + + // Set the resource + $helperInstance->setSocketResource($socketResource); + + // Resolve any session ids; 0 = IP, 1 = Port + $recipientData = explode(':', HubTools::resolveSessionId($packageData['recipient'])); + + // Set ip/port + $helperInstance->setAddress($recipientData[0]); + $helperInstance->setPort($recipientData[1]); + + // Debug message + $helperInstance->debugOutput('CONNECTION: Connecting to ' . $recipientData[0] . ':' . $recipientData[1]); + + // Now connect to it + if (!@socket_connect($socketResource, $recipientData[0], $recipientData[1])) { + // Get socket error code for verification + $socketError = socket_last_error($socketResource); + + // And throw again, but not for 'Operation now in progress', we should wait a little + if ($socketError != 115) { + // Get error message + $errorMessage = socket_strerror($socketError); + + // Shutdown this socket + $helperInstance->shutdownSocket($socketResource); + + // Throw it again + throw new InvalidSocketException(array($helperInstance, gettype($socketResource), $socketError, $errorMessage), BaseListener::EXCEPTION_INVALID_SOCKET); + } else { + // Debug output + $helperInstance->debugOutput('CONNECTION: Operation is in progress, maybe recipient is down?'); + } + } // END - if + + // Okay, that should be it. So return it... + return $socketResource; + } +} + +// [EOF] +?> diff --git a/application/hub/main/helper/connection/udp/.htaccess b/application/hub/main/helper/connection/udp/.htaccess new file mode 100644 index 000000000..3a4288278 --- /dev/null +++ b/application/hub/main/helper/connection/udp/.htaccess @@ -0,0 +1 @@ +Deny from all diff --git a/application/hub/main/helper/connection/udp/class_UdpConnectionHelper.php b/application/hub/main/helper/connection/udp/class_UdpConnectionHelper.php new file mode 100644 index 000000000..f4da32703 --- /dev/null +++ b/application/hub/main/helper/connection/udp/class_UdpConnectionHelper.php @@ -0,0 +1,51 @@ + + * @version 0.0.0 + * @copyright Copyright (c) 2007, 2008 Roland Haeder, 2009, 2010 Core Developer Team + * @license GNU GPL 3.0 or any newer version + * @link http://www.ship-simu.org + * @todo Find an interface for hub helper + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +class UdpConnectionHelper extends BaseConnectionHelper { + /** + * Protected constructor + * + * @return void + */ + protected function __construct () { + // Call parent constructor + parent::__construct(__CLASS__); + + // Set protocol + $this->setProtocol('udp'); + } + + /** + * Creates a socket resource ("connection") for given recipient in package data + * + * @param $packageData Raw package data + * @return $socketResource Socket resource + */ + public static function createConnectionFromPackageData (array $packageData) { + die(); + } +} + +// [EOF] +?> diff --git a/application/hub/main/helper/hub/class_ b/application/hub/main/helper/hub/class_ index 845c5a996..4ddf295bf 100644 --- a/application/hub/main/helper/hub/class_ +++ b/application/hub/main/helper/hub/class_ @@ -45,12 +45,6 @@ class Hub???Helper extends BaseHubHelper { // Return the prepared instance return $helperInstance; } - - /** - * "Getter" for package tags in a simple array - * - * @return $tags An array with all tags for the currently handled package - */ } // [EOF] diff --git a/application/hub/main/helper/hub/class_BaseHubHelper.php b/application/hub/main/helper/hub/class_BaseHubHelper.php index 54f8157a9..1803959d0 100644 --- a/application/hub/main/helper/hub/class_BaseHubHelper.php +++ b/application/hub/main/helper/hub/class_BaseHubHelper.php @@ -1,6 +1,6 @@ * @version 0.0.0 @@ -21,12 +21,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ -class BaseHubHelper extends BaseHelper { - /** - * An instance of a node - */ - private $nodeInstance = null; - +class BaseHubHelper extends BaseHubSystem { /** * Protected constructor * @@ -37,25 +32,6 @@ class BaseHubHelper extends BaseHelper { // Call parent constructor parent::__construct($className); } - - /** - * Setter for node instance - * - * @param $nodeInstance An instance of a node node - * @return void - */ - protected final function setNodeInstance (NodeHelper $nodeInstance) { - $this->nodeInstance = $nodeInstance; - } - - /** - * Getter for node instance - * - * @return $nodeInstance An instance of a node node - */ - public final function getNodeInstance () { - return $this->nodeInstance; - } } // [EOF] diff --git a/application/hub/main/helper/hub/connection/.htaccess b/application/hub/main/helper/hub/connection/.htaccess new file mode 100644 index 000000000..3a4288278 --- /dev/null +++ b/application/hub/main/helper/hub/connection/.htaccess @@ -0,0 +1 @@ +Deny from all diff --git a/application/hub/main/helper/hub/connection/class_HubConnectionHelper.php b/application/hub/main/helper/hub/connection/class_HubConnectionHelper.php new file mode 100644 index 000000000..2d1a8e708 --- /dev/null +++ b/application/hub/main/helper/hub/connection/class_HubConnectionHelper.php @@ -0,0 +1,56 @@ + + * @version 0.0.0 + * @copyright Copyright (c) 2007, 2008 Roland Haeder, 2009, 2010 Core Developer Team + * @license GNU GPL 3.0 or any newer version + * @link http://www.ship-simu.org + * @todo Find an interface for hub helper + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +class HubConnectionHelper extends BaseHubHelper { + /** + * Protected constructor + * + * @return void + */ + protected function __construct () { + // Call parent constructor + parent::__construct(__CLASS__); + } + + /** + * "Getter" for a valid socket resource from given packae data. + * + * @param $packageData Raw package data + * @param $protocolName Protocol name (TCP/UDP) + * @return $socketResource Socket resource + */ + public static function getSocketFromPackageData (array $packageData, $protocolName) { + // Construct configuration entry for object factory + $configEntry = $protocolName . '_connection_class'; + + // And call the static method + $socketResource = call_user_func(FrameworkConfiguration::getInstance()->getConfigEntry($configEntry) . '::createConnectionFromPackageData', $packageData); + + // Return the resource + return $socketResource; + } +} + +// [EOF] +?> diff --git a/application/hub/main/helper/hub/connection/class_HubSelfConnectHelper.php b/application/hub/main/helper/hub/connection/class_HubSelfConnectHelper.php new file mode 100644 index 000000000..53ce43650 --- /dev/null +++ b/application/hub/main/helper/hub/connection/class_HubSelfConnectHelper.php @@ -0,0 +1,60 @@ + + * @version 0.0.0 + * @copyright Copyright (c) 2007, 2008 Roland Haeder, 2009, 2010 Core Developer Team + * @license GNU GPL 3.0 or any newer version + * @link http://www.ship-simu.org + * @todo Find an interface for hub helper + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +class HubSelfConnectHelper extends BaseHubHelper { + /** + * Protected constructor + * + * @return void + */ + protected function __construct () { + // Call parent constructor + parent::__construct(__CLASS__); + } + + /** + * Creates the helper class + * + * @return $helperInstance A prepared instance of this helper + */ + public final static function createHubSelfConnectHelper () { + // Get new instance + $helperInstance = new HubSelfConnectHelper(); + + // Return the prepared instance + return $helperInstance; + } + + /** + * Do the self-connect attempt by delivering a package to ourselfs + * + * @return void + */ + public function doSelfConnect () { + $this->partialStub('Not yet finished.'); + } +} + +// [EOF] +?> diff --git a/application/hub/main/listener/class_BaseListener.php b/application/hub/main/listener/class_BaseListener.php index 1a767f9cb..5270a83d4 100644 --- a/application/hub/main/listener/class_BaseListener.php +++ b/application/hub/main/listener/class_BaseListener.php @@ -51,11 +51,6 @@ class BaseListener extends BaseHubSystem implements Visitable { */ private $poolInstance = null; - /** - * A network package handler instance - */ - private $packageInstance = null; - /** * Protected constructor * @@ -202,7 +197,7 @@ class BaseListener extends BaseHubSystem implements Visitable { * @param $poolInstance The peer pool instance we shall set * @return void */ - protected final function setPoolInstance (Poolablepeer $poolInstance) { + protected final function setPoolInstance (PoolablePeer $poolInstance) { $this->poolInstance = $poolInstance; } @@ -215,25 +210,6 @@ class BaseListener extends BaseHubSystem implements Visitable { return $this->poolInstance; } - /** - * Setter for network package handler instance - * - * @param $packageInstance The network package handler instance we shall set - * @return void - */ - protected final function setPackageInstance (Networkable $packageInstance) { - $this->packageInstance = $packageInstance; - } - - /** - * Getter for network package handler instance - * - * @return $packageInstance The network package handler instance we shall set - */ - protected final function getPackageInstance () { - return $this->packageInstance; - } - /** * Registeres the given socket resource for "this" listener instance. This * will be done in a seperate class to allow package writers to use it diff --git a/application/hub/main/listener/class_BaseListenerDecorator.php b/application/hub/main/listener/class_BaseListenerDecorator.php index 5b4d71845..68fd99454 100644 --- a/application/hub/main/listener/class_BaseListenerDecorator.php +++ b/application/hub/main/listener/class_BaseListenerDecorator.php @@ -106,6 +106,15 @@ class BaseListenerDecorator extends BaseDecorator implements Visitable { protected final function setListenerType ($listenerType) { $this->listenerType = $listenerType; } + + /** + * Getter for peer pool instance + * + * @return $poolInstance The peer pool instance we shall set + */ + public final function getPoolInstance () { + return $this->getListenerInstance()->getPoolInstance(); + } } // [EOF] diff --git a/application/hub/main/nodes/class_BaseHubNode.php b/application/hub/main/nodes/class_BaseHubNode.php index 243cb14f5..f27af3018 100644 --- a/application/hub/main/nodes/class_BaseHubNode.php +++ b/application/hub/main/nodes/class_BaseHubNode.php @@ -441,7 +441,10 @@ class BaseHubNode extends BaseHubSystem implements Updateable { /** * Announces this hub to the upper (bootstrap or list) hubs. After this is - * successfully done the given task is unregistered from the handler. + * successfully done the given task is unregistered from the handler. This + * might look a bit overloaded here but the announcement phase isn't a + * simple "Hello there" message, it may later on also contain more + * informations like the object list. * * @param $taskInstance The task instance running this announcement * @return void @@ -456,7 +459,7 @@ class BaseHubNode extends BaseHubSystem implements Updateable { } // END - if // Debug output - $this->debugOutput('HUB: Self-announcement: START (taskInstance=' . $taskInstance->__toString(). ')'); + $this->debugOutput('HUB: Self Announcement: START (taskInstance=' . $taskInstance->__toString(). ')'); // Get a helper instance $helperInstance = ObjectFactory::createObjectByConfiguredName('hub_announcement_helper_class', array($this)); @@ -477,7 +480,29 @@ class BaseHubNode extends BaseHubSystem implements Updateable { $this->getStateInstance()->nodeAnnouncedToUpperHubs(); // Debug output - $this->debugOutput('HUB: Self-announcement: FINISHED'); + $this->debugOutput('HUB: Self Announcement: FINISHED'); + } + + /** + * Does a self-connect attempt on the public IP address. This should make + * it sure, we are reachable from outside world. For this kind of package we + * don't need that overload we have in the announcement phase. + * + * @param $taskInstance The task instance running this announcement + * @return void + */ + public function doSelfConnection (Taskable $taskInstance) { + // Debug output + $this->debugOutput('HUB: Self Connection: START (taskInstance=' . $taskInstance->__toString(). ')'); + + // Get a helper instance + $helperInstance = ObjectFactory::createObjectByConfiguredName('hub_self_connect_helper_class', array($this)); + + // And send the package away + $helperInstance->doSelfConnect(); + + // Debug output + $this->debugOutput('HUB: Self Connection: FINISHED'); } /** diff --git a/application/hub/main/package/class_NetworkPackage.php b/application/hub/main/package/class_NetworkPackage.php index f009ef73b..52b2c3ec9 100644 --- a/application/hub/main/package/class_NetworkPackage.php +++ b/application/hub/main/package/class_NetworkPackage.php @@ -62,6 +62,11 @@ class NetworkPackage extends BaseFrameworkSystem implements Deliverable, Registe */ const PACKAGE_TAGS_SEPERATOR = ';'; + /** + * Raw package data seperator + */ + const PACKAGE_DATA_SEPERATOR = '|'; + /** * Stacker name for "undeclared" packages */ @@ -72,6 +77,11 @@ class NetworkPackage extends BaseFrameworkSystem implements Deliverable, Registe */ const STACKER_NAME_DECLARED = 'declared'; + /** + * Stacker name for "out-going" packages + */ + const STACKER_NAME_OUTGOING = 'outgoing'; + /** * Network target (alias): 'upper hubs' */ @@ -199,7 +209,35 @@ class NetworkPackage extends BaseFrameworkSystem implements Deliverable, Registe // Now discover the right protocol $socketResource = $discoveryInstance->discoverSocket($packageData); - die($socketResource); + + // We have to put this socket in our registry, so get an instance + $registryInstance = SocketRegistry::createSocketRegistry(); + + // Get the listener from registry + $connectionInstance = Registry::getRegistry()->getInstance('connection'); + + // Is it not there? + if (!$registryInstance->isSocketRegistered($connectionInstance, $socketResource)) { + // Then register it + $registryInstance->registerSocket($connectionInstance, $socketResource, $packageData); + } // END - if + + // We enqueue it again, but now in the out-going queue + $this->getStackerInstance()->pushNamed(self::STACKER_NAME_OUTGOING, $packageData); + } + + /** + * Sends waiting packages + * + * @param $packageData Raw package data + * @return void + */ + private function sendOutgoingPackage (array $packageData) { + // Get the right connection instance + $connectionInstance = SocketRegistry::createSocketRegistry()->getHandlerInstanceFromPackageData($packageData); + + // Sent it away (we catch exceptions one method above + $connectionInstance->sendRawPackageData($packageData); } /** @@ -262,6 +300,19 @@ class NetworkPackage extends BaseFrameworkSystem implements Deliverable, Registe return $isDeclared; } + /** + * Checks wether a package should be sent out + * + * @return $isWaitingDelivery Wether a package is waiting for delivery + */ + public function isPackageWaitingDelivery () { + // Check wether the stacker is not empty + $isWaitingDelivery = (($this->getStackerInstance()->isStackInitialized(self::STACKER_NAME_OUTGOING)) && (!$this->getStackerInstance()->isStackEmpty(self::STACKER_NAME_OUTGOING))); + + // Return the result + return $isWaitingDelivery; + } + /** * Delivers an enqueued package to the stated destination. If a non-session * id is provided, recipient resolver is being asked (and instanced once). @@ -315,6 +366,34 @@ class NetworkPackage extends BaseFrameworkSystem implements Deliverable, Registe // And remove it finally $this->getStackerInstance()->popNamed(self::STACKER_NAME_DECLARED); } + + /** + * Sends waiting packages out for delivery + * + * @return void + */ + public function sentWaitingPackage () { + // Sanity check if we have packages waiting for delivery + if (!$this->isPackageWaitingDelivery()) { + // This is not fatal but should be avoided + // @TODO Add some logging here + return; + } // END - if + + // Get the package again + $packageData = $this->getStackerInstance()->getNamed(self::STACKER_NAME_OUTGOING); + + // Now try to send it + try { + $this->sendOutgoingPackage($packageData); + + // And remove it finally when it has been fully delivered + $this->getStackerInstance()->popNamed(self::STACKER_NAME_OUTGOING); + } catch (InvalidSocketException $e) { + // Output exception message + $this->debugOutput('PACKAGE: Package was not delivered: ' . $e->getMessage()); + } + } } // [EOF] diff --git a/application/hub/main/pools/peer/class_DefaultPeerPool.php b/application/hub/main/pools/peer/class_DefaultPeerPool.php index c6b1c986a..bb76056fe 100644 --- a/application/hub/main/pools/peer/class_DefaultPeerPool.php +++ b/application/hub/main/pools/peer/class_DefaultPeerPool.php @@ -126,7 +126,33 @@ class DefaultPeerPool extends BasePool implements PoolablePeer { // Return it return $sockets; } + + /** + * "Getter" for a valid socket resource from given packae data. + * + * @param $packageData Raw package data + * @return $socketResource Socket resource + */ + public function getSocketFromPackageData (array $packageData) { + // Default is no socket + $socketResource = false; + + // Get all sockets and check them, skip the server socket + foreach ($this->getAllSockets() as $socket) { + // Is this a server socket? + if ($socket === $this->getListenerInstance()->getSocketResource()) { + // Skip this + continue; + } // END - if + + // @TODO Check for IP + die(__METHOD__.':'.print_r($packageData, true)); + } // END - foreach + + // Return the determined socket resource + return $socketResource; + } } -// +// [EOF] ?> diff --git a/application/hub/main/registry/socket/.htaccess b/application/hub/main/registry/socket/.htaccess new file mode 100644 index 000000000..3a4288278 --- /dev/null +++ b/application/hub/main/registry/socket/.htaccess @@ -0,0 +1 @@ +Deny from all diff --git a/application/hub/main/registry/socket/class_SocketRegistry.php b/application/hub/main/registry/socket/class_SocketRegistry.php new file mode 100644 index 000000000..60c805971 --- /dev/null +++ b/application/hub/main/registry/socket/class_SocketRegistry.php @@ -0,0 +1,237 @@ + + * @version 0.0.0 + * @copyright Copyright (c) 2007, 2008 Roland Haeder, 2009, 2010 Hub Developer Team + * @license GNU GPL 3.0 or any newer version + * @link http://www.ship-simu.org + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +class SocketRegistry extends BaseRegistry implements Register, RegisterableSocket { + // Exception constants + const SOCKET_NOT_REGISTERED = 0xd00; + + /** + * Instance of this class + */ + private static $registryInstance = null; + + /** + * Protected constructor + * + * @return void + */ + protected function __construct () { + // Call parent constructor + parent::__construct(__CLASS__); + } + + /** + * Creates a singleton instance of this registry class + * + * @return $registryInstance An instance of this class + */ + public final static function createSocketRegistry () { + // Is an instance there? + if (is_null(self::$registryInstance)) { + // Not yet, so create one + self::$registryInstance = new SocketRegistry(); + } // END - if + + // Return the instance + return self::$registryInstance; + } + + /** + * "Getter" to get a string respresentation for a key for the sub-registry + * in this format: class:protocol:port + * + * @param $protocolInstance An instance of a ProtocolHandler class + * @return $key A string representation of the socket for the registry + */ + private function getSubRegistryKey (ProtocolHandler $protocolInstance) { + // Get protocol and port number and add both together + $key = sprintf("%s:%s:%s", + $protocolInstance->__toString(), + $protocolInstance->getProtocol(), + $protocolInstance->getPort() + ); + + // Return resulting key + return $key; + } + + /** + * "Getter" to get a string respresentation of the protocol + * + * @param $protocolInstance An instance of a ProtocolHandler class + * @return $key A string representation of the protocol for the registry + */ + private function getRegistryKeyFromProtocol (ProtocolHandler $protocolInstance) { + // Get the key + $key = $protocolInstance->getProtocol(); + + // Return resulting key + return $key; + } + + /** + * Checks wether the given protocol is registered + * + * @param $protocolInstance An instance of a ProtocolHandler class + * @return $isRegistered Wether the protocol is registered + */ + private function isProtocolRegistered (ProtocolHandler $protocolInstance) { + // Get the key + $key = $this->getRegistryKeyFromProtocol($protocolInstance); + + // Determine it + $isRegistered = $this->instanceExists($key); + + // Return result + return $isRegistered; + } + + /** + * Checks wether given socket resource is registered. If $socketResource is + * false only the instance will be checked. + * + * @param $protocolInstance An instance of a ProtocolHandler class + * @param $socketResource A valid socket resource + * @return $isRegistered Wether the given socket resource is registered + */ + public function isSocketRegistered (ProtocolHandler $protocolInstance, $socketResource) { + // Default is not registered + $isRegistered = false; + + // First, check for the instance, there can be only once + if ($this->isProtocolRegistered($protocolInstance)) { + // That one is found so "get" a registry key from it + $key = $this->getRegistryKeyFromProtocol($protocolInstance); + + // Get the registry + $registryInstance = $this->getInstance($key); + + // "Get" a key for the socket + $socketKey = $this->getSubRegistryKey($protocolInstance); + + // And simply ask it + $isRegistered = $registryInstance->instanceExists($socketKey); + } // END - if + + // Return the result + return $isRegistered; + } + + /** + * Registeres given socket for listener or throws an exception if it is already registered + * + * @param $protocolInstance An instance of a ProtocolHandler class + * @param $socketResource A valid socket resource + * @param $packageData Optional raw package data + * @throws SocketAlreadyRegisteredException If the given socket is already registered + * @return void + */ + public function registerSocket (ProtocolHandler $protocolInstance, $socketResource, array $packageData = array()) { + // Is the socket already registered? + if ($this->isSocketRegistered($protocolInstance, $socketResource)) { + // Throw the exception + throw new SocketAlreadyRegisteredException($protocolInstance, BaseListener::EXCEPTION_SOCKET_ALREADY_REGISTERED); + } // END - if + + // Does the instance exist? + if (!$this->isProtocolRegistered($protocolInstance)) { + // No, not found so we create a sub registry (not needed to configure!) + $registryInstance = SubRegistry::createSubRegistry(); + + // Now we can create the sub-registry for this protocol + $this->addInstance($this->getRegistryKeyFromProtocol($protocolInstance), $registryInstance); + } else { + // Get the sub-registry back + $registryInstance = $this->getInstance($this->getRegistryKeyFromProtocol($protocolInstance)); + } + + // Get a key for sub-registries + $socketKey = $this->getSubRegistryKey($protocolInstance); + + // Get a socket container + $socketInstance = ObjectFactory::CreateObjectByConfiguredName('socket_container_class', array($socketResource, $protocolInstance, $packageData)); + + // We have a sub-registry, the socket key and the socket, now we need to put all together + $registryInstance->addInstance($socketKey, $socketInstance); + } + + /** + * Getter for given listener's socket resource + * + * @param $protocolInstance An instance of a ProtocolHandler class + * @return $socketResource A valid socket resource + * @throws NoSocketRegisteredException If the requested socket is not registered + */ + public function getRegisteredSocketResource (ProtocolHandler $protocolInstance) { + // The socket must be registered before we can return it + if (!$this->isSocketRegistered($protocolInstance, false)) { + // Throw the exception + throw new NoSocketRegisteredException ($protocolInstance, self::SOCKET_NOT_REGISTERED); + } // END - if + + // Now get the key from the protocol + $key = $this->getRegistryKeyFromProtocol($protocolInstance); + + // And get the registry + $registryInstance = $this->getInstance($key); + + // Get a socket key + $socketKey = $this->getSubRegistryKey($protocolInstance); + + // And the final socket resource + $socketResource = $registryInstance->getInstance($socketKey)->getSocketResource(); + + // Return the resource + return $socketResource; + } + + /** + * "Getter" for protocol/connection instance from given package data + * + * @param $packageData Raw package data + * @return $protocolInstance An instance of a ProtocolHandler class + */ + public function getHandlerInstanceFromPackageData (array $packageData) { + // Init protocol instance + $protocolInstance = null; + + // Get all keys and check them + foreach ($this->getInstanceRegistry() as $key=>$registryInstance) { + // This is always a SubRegistry instance + foreach ($registryInstance->getInstanceRegistry() as $subKey=>$containerInstance) { + // This is a SocketContainer instance, so does the recipient match? + if ($containerInstance->ifAddressMatches($packageData['recipient'])) { + // Found one, so get the protocol instance and abort + $protocolInstance = $containerInstance->getProtocolInstance(); + break; + } // END - if + } // END - foreach + } // END - foreach + + // Return the protocol instance + return $protocolInstance; + } +} + +// [EOF] +?> diff --git a/application/hub/main/tasks/hub/class_HubSelfConnectTask.php b/application/hub/main/tasks/hub/class_HubSelfConnectTask.php index 624744ed2..1700db1ff 100644 --- a/application/hub/main/tasks/hub/class_HubSelfConnectTask.php +++ b/application/hub/main/tasks/hub/class_HubSelfConnectTask.php @@ -63,7 +63,8 @@ class HubSelfConnectTask extends BaseTask implements Taskable, Visitable { * @return void */ public function executeTask () { - $this->partialStub('Unimplemented task.'); + // Get the node instance and try it + Registry::getRegistry()->getInstance('node')->doSelfConnection($this); } } diff --git a/application/hub/main/tasks/network/class_NetworkPackageWriterTask.php b/application/hub/main/tasks/network/class_NetworkPackageWriterTask.php index 9ff649d31..15b974f96 100644 --- a/application/hub/main/tasks/network/class_NetworkPackageWriterTask.php +++ b/application/hub/main/tasks/network/class_NetworkPackageWriterTask.php @@ -70,8 +70,11 @@ class NetworkPackageWriterTask extends BaseTask implements Taskable, Visitable { // Okay, then deliver (better discover its recipients) this package $packageInstance->declareEnqueuedPackage(); } elseif ($packageInstance->isPackageDeclared()) { - // Finally deliver a package + // Prepare package for delivery $packageInstance->deliverDeclaredPackage(); + } elseif ($packageInstance->isPackageWaitingDelivery()) { + // Sent it finally out + $packageInstance->sentWaitingPackage(); } } } diff --git a/application/hub/main/tools/.htaccess b/application/hub/main/tools/.htaccess new file mode 100644 index 000000000..3a4288278 --- /dev/null +++ b/application/hub/main/tools/.htaccess @@ -0,0 +1 @@ +Deny from all diff --git a/application/hub/main/tools/class_HubTools.php b/application/hub/main/tools/class_HubTools.php new file mode 100644 index 000000000..fac5c2acf --- /dev/null +++ b/application/hub/main/tools/class_HubTools.php @@ -0,0 +1,56 @@ + + * @version 0.0.0 + * @copyright Copyright (c) 2007, 2008 Roland Haeder, 2009, 2010 Hub Developer Team + * @license GNU GPL 3.0 or any newer version + * @link http://www.ship-simu.org + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +class HubTools extends BaseFrameworkSystem { + /** + * Protected constructor + * + * @return void + */ + protected function __construct () { + // Call parent constructor + parent::__construct(__CLASS__); + } + + /** + * Resolves given session id into a ip:port string, if ip:port is set, it won't be translated + * + * @param $sessionId Session id or ip:port string + * @return $recipient Recipient as ip:port string + */ + public static function resolveSessionId ($sessionId) { + // Default is direct ip:port + $recipient = $sessionId; + + // Does it match a direct ip:port? (hint: see www.regexlib.com for the regular expression) + if (!preg_match('/((?:2[0-5]{2}|1\d{2}|[1-9]\d|[1-9])\.(?:(?:2[0-5]{2}|1\d{2}|[1-9]\d|\d)\.){2}(?:2[0-5]{2}|1\d{2}|[1-9]\d|\d)):(\d|[1-9]\d|[1-9]\d{2,3}|[1-5]\d{4}|6[0-4]\d{3}|654\d{2}|655[0-2]\d|6553[0-5])/', $sessionId)) { + die(__METHOD__.': sessionId=' . $sessionId . "\n"); + } // END - if + + // Return it + return $recipient; + } +} + +// [EOF] +?> -- 2.39.2