application/hub/exceptions/.htaccess -text svneol=unset#text/plain
application/hub/exceptions/announcement/.htaccess -text svneol=unset#text/plain
application/hub/exceptions/announcement/class_AnnouncementNotAcceptedException.php svneol=native#text/plain
+application/hub/exceptions/connection/.htaccess -text svneol=unset#text/plain
+application/hub/exceptions/connection/class_InvalidConnectionTypeException.php svneol=native#text/plain
application/hub/exceptions/hub/.htaccess -text svneol=unset#text/plain
application/hub/exceptions/hub/class_HubAlreadyAnnouncedException.php svneol=native#text/plain
application/hub/exceptions/ids/.htaccess -text svneol=unset#text/plain
--- /dev/null
+Deny from all
--- /dev/null
+<?php
+/**
+ * This exception is thrown when an invalid connection type is being detected
+ *
+ * @author Roland Haeder <webmaster@ship-simu.org>
+ * @version 0.0.0
+ * @copyright Copyright (c) 2007, 2008 Roland Haeder, 2009 - 2012 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 <http://www.gnu.org/licenses/>.
+ */
+class InvalidConnectionTypeException extends FrameworkException {
+ /**
+ * The super constructor for all exceptions
+ *
+ * @param $messageArray Error message array
+ * @param $code Error code
+ * @return void
+ */
+ public function __construct (array $messageArray, $code) {
+ // Construct the message
+ $message = sprintf("[%s:%d] Connection type %s is invalid.",
+ $messageArray[0]->__toString(),
+ $this->getLine(),
+ $messageArray[1]
+ );
+
+ // Call parent exception constructor
+ parent::__construct($message, $code);
+ }
+}
+
+// [EOF]
+?>
* matching socket resource.
*
* @param $packageData Raw package data array
- * @param $packageInstance A Deliverable instance
+ * @param $connectionType Type of connection, can be 'incoming' or 'outgoing', *NEVER* 'server'!
* @return $socketResource A valid socket resource
+ * @throws NoListGroupException If the procol group is not found in peer list
+ * @throws NullPointerException If listenerInstance is NULL
*/
- function discoverSocket (array $packageData);
+ function discoverSocket (array $packageData, $connectionType);
}
// [EOF]
* Processes raw data from given resource. This is mostly useful for TCP
* package handling and is implemented in the TcpListener class
*
- * @param $resource A valid resource identifier
+ * @param $resourceArray A valid socket resource array
* @return void
* @throws InvalidResourceException If the given resource is invalid
*/
- function processRawDataFromResource ($resource);
+ function processRawDataFromResource (array $resourceArray);
/**
* Checks whether decoded data is pending for further processing.
* Adds a socket resource to the peer pool
*
* @param $socketResource A valid (must be!) socket resource
+ * @param $connectionType Type of connection, can only be 'incoming', 'outgoing' or 'server'
* @return void
+ * @throws InvalidSocketException If the given resource is invalid or errorous
*/
- function addPeer ($socketResource);
+ function addPeer ($socketResource, $connectionType);
+
+ /**
+ * Getter for array of all socket resource arrays
+ *
+ * @return $sockets An array with all socket arrays
+ */
+ function getAllSockets ();
+
+ /**
+ * Getter for array of all socket resources
+ *
+ * @return $sockets An array with all sockets
+ */
+ function getAllSingleSockets ();
+
+ /**
+ * "Getter" for all sockets of specified type
+ *
+ * @param $connectionType Type of connection, can only be 'incoming', 'outgoing' or 'server'
+ * @return $sockets An array with sockets of given type
+ */
+ function getSocketsByConnectionType ($connectionType);
}
// [EOF]
* "Getter" for a valid socket resource from given packae data.
*
* @param $packageData Raw package data
+ * @param $connectionType Type of connection, can be 'incoming', 'outgoing', 'server' or default
* @return $socketResource Socket resource
+ * @throws InvalidConnectionTypeException If the provided connection type is not valid
*/
- function getSocketFromPackageData (array $packageData);
+ function getSocketFromPackageData (array $packageData, $connectionType = NULL);
}
// [EOF]
const EXCEPTION_UNSUPPORTED_ERROR_HANDLER = 0x900;
const EXCEPTION_CHUNK_ALREADY_ASSEMBLED = 0x901;
const EXCEPTION_ANNOUNCEMENT_NOT_ACCEPTED = 0x902;
+ const EXCEPTION_INVALID_CONNECTION_TYPE = 0x903;
// Message status codes
const MESSAGE_STATUS_CODE_OKAY = 'OKAY';
* matching socket resource for that protocol.
*
* @param $packageData Raw package data array
+ * @param $connectionType Type of connection, can be 'incoming' or 'outgoing', *NEVER* 'server'!
* @return $socketResource A valid socket resource or FALSE if an error occured
* @throws NoListGroupException If the procol group is not found in peer list
* @throws NullPointerException If listenerInstance is NULL
*/
- public function discoverSocket (array $packageData) {
+ public function discoverSocket (array $packageData, $connectionType) {
+ // Assert on type
+ assert($connectionType != BaseConnectionHelper::CONNECTION_TYPE_SERVER);
+
// Determine protocol name
$protocolName = $this->determineProtocolByPackageData($packageData);
* instance and pass over the whole package data to get the right
* socket.
*/
- $socketResource = $listenerInstance->getPoolInstance()->getSocketFromPackageData($packageData);
+ $socketResource = $listenerInstance->getPoolInstance()->getSocketFromPackageData($packageData, $connectionType);
// Debug message
if (is_resource($socketResource)) {
* Processes raw data from given resource. This is mostly useful for TCP
* package handling and is implemented in the TcpListener class
*
- * @param $resource A valid resource identifier
+ * @param $resource A valid socket resource array
* @return void
*/
- public function processRawDataFromResource ($resource) {
+ public function processRawDataFromResource (array $socketArray) {
// Check the resource
- if (!is_resource($resource)) {
+ if ((!isset($socketArray[BasePool::SOCKET_ARRAY_RESOURCE])) || (!is_resource($socketArray[BasePool::SOCKET_ARRAY_RESOURCE]))) {
// Throw an exception
throw new InvalidResourceException($this, self::EXCEPTION_INVALID_RESOURCE);
} // END - if
$decodedData = false;
// Debug message
- /* NOISY-DEBUG: */ $this->debugOutput('TCP-HANDLER: Handling TCP package from peer ' . $resource . ',last error=' . socket_strerror(socket_last_error($resource)));
+ /* NOISY-DEBUG: */ $this->debugOutput('TCP-HANDLER: Handling TCP package from resource=' . $socketArray[BasePool::SOCKET_ARRAY_RESOURCE] . ',type=' . $socketArray[BasePool::SOCKET_ARRAY_CONN_TYPE] . ',last error=' . socket_strerror(socket_last_error($socketArray[BasePool::SOCKET_ARRAY_RESOURCE])));
/*
* Read the raw data from socket. If you change PHP_BINARY_READ to
* PHP_NORMAL_READ, this line will endless block. This script does only
* provide simultanous threads, not real.
*/
- $rawData = socket_read($resource, $this->getConfigInstance()->getConfigEntry('tcp_buffer_length'), PHP_BINARY_READ);
+ $rawData = socket_read($socketArray[BasePool::SOCKET_ARRAY_RESOURCE], $this->getConfigInstance()->getConfigEntry('tcp_buffer_length'), PHP_BINARY_READ);
// Debug output of read data length
- /* NOISY-DEBUG: */ $this->debugOutput('TCP-HANDLER: rawData[' . gettype($rawData) . ']=' . strlen($rawData) . ',resource=' . $resource . ',error=' . socket_strerror(socket_last_error($resource)));
+ /* NOISY-DEBUG: */ $this->debugOutput('TCP-HANDLER: rawData[' . gettype($rawData) . ']=' . strlen($rawData) . ',resource=' . $socketArray[BasePool::SOCKET_ARRAY_RESOURCE] . ',error=' . socket_strerror(socket_last_error($socketArray[BasePool::SOCKET_ARRAY_RESOURCE])));
// Is it valid?
- if (socket_last_error($resource) == 11) {
+ if (socket_last_error($socketArray[BasePool::SOCKET_ARRAY_RESOURCE]) == 11) {
// Debug message
- /* NOISY-DEBUG: */ $this->debugOutput('TCP-HANDLER: Ignoring error 11 (Resource temporary unavailable) from socket resource=' . $resource);
+ /* NOISY-DEBUG: */ $this->debugOutput('TCP-HANDLER: Ignoring error 11 (Resource temporary unavailable) from socket resource=' . $socketArray[BasePool::SOCKET_ARRAY_RESOURCE]);
/*
* Error code 11 (Resource temporary unavailable) can be safely
* ignored on non-blocking sockets. The socket is currently not
* sending any data.
*/
- socket_clear_error($resource);
- } elseif (($rawData === false) || (socket_last_error($resource) > 0)) {
+ socket_clear_error($socketArray[BasePool::SOCKET_ARRAY_RESOURCE]);
+ } elseif (($rawData === false) || (socket_last_error($socketArray[BasePool::SOCKET_ARRAY_RESOURCE]) > 0)) {
// Network error or connection lost
- $this->setErrorCode(socket_last_error($resource));
+ $this->setErrorCode(socket_last_error($socketArray[BasePool::SOCKET_ARRAY_RESOURCE]));
} elseif (empty($rawData)) {
// The peer did send nothing to us
$this->setErrorCode(self::SOCKET_ERROR_EMPTY_DATA);
* Processes raw data from given resource. This is mostly useful for TCP
* package handling and is implemented in the TcpListener class
*
- * @param $resource A valid resource identifier
+ * @param $socketArray A valid socket resource array
* @return void
* @throws InvalidResourceException If the given resource is invalid
* @todo 0%
*/
- public function processRawDataFromResource ($resource) {
+ public function processRawDataFromResource (array $socketArray) {
// Check the resource
- if (!is_resource($resource)) {
+ if ((!isset($socketArray[BasePool::SOCKET_ARRAY_RESOURCE])) || (!is_resource($socketArray[BasePool::SOCKET_ARRAY_RESOURCE]))) {
// Throw an exception
throw new InvalidResourceException($this, self::EXCEPTION_INVALID_RESOURCE);
} // END - if
// Implement processing here
- $this->partialStub('Please implement this method. resource=' . $resource);
+ $this->partialStub('Please implement this method. resource=' . $socketArray[BasePool::SOCKET_ARRAY_RESOURCE] . ',type=' . $socketArray[BasePool::SOCKET_ARRRAY_CONN_TYPE]);
}
}
// Exception codes
const EXCEPTION_UNSUPPORTED_ERROR_HANDLER = 0x900;
+ /**
+ * Connection type 'incoming'
+ */
+ const CONNECTION_TYPE_INCOMING = 'incoming';
+
+ /**
+ * Connection type 'outgoing'
+ */
+ const CONNECTION_TYPE_OUTGOING = 'outgoing';
+
+ /**
+ * Connection type 'server'
+ */
+ const CONNECTION_TYPE_SERVER = 'server';
+
/**
* Protocol used
*/
$poolInstance = ObjectFactory::createObjectByConfiguredName('node_pool_class', array($this));
// Add main socket
- $poolInstance->addPeer($mainSocket);
+ $poolInstance->addPeer($mainSocket, BaseConnectionHelper::CONNECTION_TYPE_SERVER);
// And add it to this listener
$this->setPoolInstance($poolInstance);
*/
public function doListen () {
// Get all readers
- $readers = $this->getPoolInstance()->getAllSockets();
+ $readers = $this->getPoolInstance()->getAllSingleSockets();
$writers = array();
$excepts = array();
$newSocket = socket_accept($this->getSocketResource());
// Debug message
- /* NOISY-DEBUG: */ $this->debugOutput('[' . __METHOD__ . ':' . __LINE__ . ']: newSocket=' . $newSocket . ',server=' .$this->getSocketResource());
+ //* NOISY-DEBUG: */ $this->debugOutput('[' . __METHOD__ . ':' . __LINE__ . ']: newSocket=' . $newSocket . ',server=' .$this->getSocketResource());
// Array for timeout settings
$options = array(
} // END - if
// Add it to the peers
- $this->getPoolInstance()->addPeer($newSocket);
+ $this->getPoolInstance()->addPeer($newSocket, BaseConnectionHelper::CONNECTION_TYPE_INCOMING);
// Get peer name
if (!socket_getpeername($newSocket, $peerName)) {
$currentSocket = $this->getIteratorInstance()->current();
// Handle it here, if not main socket
- /* NOISY-DEBUG: */ $this->debugOutput('TCP-LISTENER: currentSocket=' . $currentSocket . ',server=' . $this->getSocketResource());
+ /* NOISY-DEBUG: */ $this->debugOutput('TCP-LISTENER: currentSocket=' . $currentSocket[BasePool::SOCKET_ARRAY_RESOURCE] . ',type=' . $currentSocket[BasePool::SOCKET_ARRAY_CONN_TYPE] . ',server=' . $this->getSocketResource());
if ($currentSocket != $this->getSocketResource()) {
// ... or else it will raise warnings like 'Transport endpoint is not connected'
$this->getHandlerInstance()->processRawDataFromResource($currentSocket);
$discoveryInstance = SocketDiscoveryFactory::createSocketDiscoveryInstance();
// Now discover the right protocol
- $socketResource = $discoveryInstance->discoverSocket($packageData);
+ $socketResource = $discoveryInstance->discoverSocket($packageData, BaseConnectionHelper::CONNECTION_TYPE_OUTGOING);
// Debug message
//* NOISY-DEBUG: */ $this->debugOutput('NETWORK-PACKAGE: Reached line ' . __LINE__ . ' after discoverSocket() has been called.');
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
class BasePool extends BaseHubSystem implements Visitable {
+ /**
+ * Socket array elements
+ */
+ const SOCKET_ARRAY_RESOURCE = 'resource';
+ const SOCKET_ARRAY_CONN_TYPE = 'connection_type';
+
/**
* A list of pool entries
*/
private $poolEntriesInstance = NULL;
+ /**
+ * An array with all valid connection types
+ */
+ private $connectionTypes = array();
+
/**
* Protected constructor
*
// Init the pool entries
$this->poolEntriesInstance = ObjectFactory::createObjectByConfiguredName('pool_entries_list_class');
+
+ // Init array of connection types
+ $this->connectionTypes = array(
+ BaseConnectionHelper::CONNECTION_TYPE_INCOMING,
+ BaseConnectionHelper::CONNECTION_TYPE_OUTGOING,
+ BaseConnectionHelper::CONNECTION_TYPE_SERVER
+ );
}
/**
// Return it
return $array;
}
+
+ /**
+ * Checks whether the given connection type is valid
+ *
+ * @param $connectionType Type of connection, can be 'incoming', 'outgoing' or 'server'
+ * @return $isValid Whether the provided connection type is valid
+ */
+ protected function isValidConnectionType ($connectionType) {
+ // Is it valid?
+ $isValid = in_array($connectionType, $this->connectionTypes, true);
+
+ // Return result
+ return $isValid;
+ }
}
// [EOF]
* Adds a socket resource to the peer pool
*
* @param $socketResource A valid (must be!) socket resource
+ * @param $connectionType Type of connection, can only be 'incoming', 'outgoing' or 'server'
* @return void
* @throws InvalidSocketException If the given resource is invalid or errorous
*/
- public function addPeer ($socketResource) {
+ public function addPeer ($socketResource, $connectionType) {
// Validate the socket
$this->validateSocket($socketResource);
// Debug message
$this->debugOutput('POOL: Adding peer ' . $peerName . ',socketResource=' . $socketResource);
+ // Construct the array
+ $socketArray = array(
+ self::SOCKET_ARRAY_RESOURCE => $socketResource,
+ self::SOCKET_ARRAY_CONN_TYPE => $connectionType
+ );
+
// Add it finally to the pool
- $this->addPoolEntry($socketResource);
+ $this->addPoolEntry($socketArray);
}
/**
return $sockets;
}
+ /**
+ * Getter for array of all socket arrays
+ *
+ * @return $sockets An array with all socket arrays
+ */
+ public final function getAllSingleSockets () {
+ // Get the array list
+ $socketArrays = $this->getArrayFromList('pool');
+
+ // Init socket array
+ $sockets = array();
+
+ // "Walk" through all socket arrays
+ foreach ($socketArrays as $socketArray) {
+ // Add the socket
+ $sockets[] = $socketArray[self::SOCKET_ARRAY_RESOURCE];
+ } // END - foreach
+
+ // Return it
+ return $sockets;
+ }
+
+ /**
+ * "Getter" for all sockets of specified type
+ *
+ * @param $connectionType Type of connection, can only be 'incoming', 'outgoing' or 'server'
+ * @return $sockets An array with sockets of given type
+ */
+ public function getSocketsByConnectionType ($connectionType) {
+ // Get the array list
+ $socketArrays = $this->getArrayFromList('pool');
+
+ // Init socket array
+ $sockets = array();
+
+ // "Walk" through all socket arrays
+ foreach ($socketArrays as $socketArray) {
+ // Does it match?
+ if ($socketArray[self::SOCKET_ARRAY_CONN_TYPE] === $connectionType) {
+ // Add the socket
+ $sockets[] = $socketArray[self::SOCKET_ARRAY_RESOURCE];
+ } // END - if
+ } // END - foreach
+
+ // Return it
+ return $sockets;
+ }
+
/**
* "Getter" for a valid socket resource from given packae data.
*
* @param $packageData Raw package data
+ * @param $connectionType Type of connection, can be 'incoming', 'outgoing', 'server' or default
* @return $socketResource Socket resource
+ * @throws InvalidConnectionTypeException If the provided connection type is not valid
*/
- public function getSocketFromPackageData (array $packageData) {
+ public function getSocketFromPackageData (array $packageData, $connectionType = NULL) {
// Default is no socket
$socketResource = false;
// Debug message
/* NOISY-DEBUG: */ $this->debugOutput('POOL: Checking ' . count($this->getAllSockets()) . ' socket(s),recipientIpArray[0]=' . $recipientIpArray[0] . ',recipientIpArray[1]=' . $recipientIpArray[1] . ' ...');
+ // Default is all sockets
+ $sockets = $this->getAllSockets();
+
+ // Is connection type set?
+ if ((is_string($connectionType)) && ($this->isValidConnectionType($connectionType))) {
+ // Then get a list of this type
+ $sockets = $this->getSocketsByConnectionType($connectionType);
+ } elseif (is_string($connectionType)) {
+ // Is not a valid connection type!
+ throw new InvalidConnectionTypeException(array($this, $connectionType), self::EXCEPTION_INVALID_CONNECTION_TYPE);
+ }
+
// Get all sockets and check them, skip the server socket
- foreach ($this->getAllSockets() as $socket) {
+ foreach ($sockets as $socketArray) {
// Is this a server socket?
- if ($socket === $this->getListenerInstance()->getSocketResource()) {
+ if ($socketArray[self::SOCKET_ARRAY_RESOURCE] === $this->getListenerInstance()->getSocketResource()) {
// Skip 'server' sockets (local socket)
- /* NOISY-DEBUG: */ $this->debugOutput('POOL: Skipping server socket ' . $socket . ' ...');
+ /* NOISY-DEBUG: */ $this->debugOutput('POOL: Skipping server socket ' . $socketArray[self::SOCKET_ARRAY_RESOURCE] . ' ...');
continue;
} // END - if
// Try to get the "peer"'s name
- if (!socket_getpeername($socket, $peerIp)) {
+ if (!socket_getpeername($socketArray[self::SOCKET_ARRAY_RESOURCE], $peerIp)) {
// Handle the socket error with given package data
- $this->handleSocketError(__METHOD__, __LINE__, $socket, explode(':', $packageData[NetworkPackage::PACKAGE_DATA_RECIPIENT]));
+ $this->handleSocketError(__METHOD__, __LINE__, $socketArray[self::SOCKET_ARRAY_RESOURCE], explode(':', $packageData[NetworkPackage::PACKAGE_DATA_RECIPIENT]));
} // END - if
// Get
// If the "peer" IP and recipient is same, use it
if ($peerIp == $recipientIpArray[0]) {
// IPs match, so take the socket and quit this loop
- $socketResource = $socket;
+ $socketResource = $socketArray[self::SOCKET_ARRAY_RESOURCE];
// Debug message
- /* NOISY-DEBUG: */ $this->debugOutput('POOL: peerIp=' . $peerIp . ' matches with recipient IP address. Taking socket=' . $socket);
+ /* NOISY-DEBUG: */ $this->debugOutput('POOL: peerIp=' . $peerIp . ' matches with recipient IP address. Taking socket=' . $socketArray[self::SOCKET_ARRAY_RESOURCE] . ',type=' . $socketArray[self::SOCKET_ARRAY_CONN_TYPE]);
break;
} // END - if
} // END - foreach