);
// Log assert
+ die($message);
syslog(LOG_WARNING, $message);
// Throw an exception here
// Set error handler
//set_error_handler('__errorHandler');
-// Set the new handler
+// Set the exception handler
set_exception_handler('hub_exception_handler');
// Init assert handling
assert_options(ASSERT_WARNING , FALSE);
assert_options(ASSERT_BAIL , TRUE);
assert_options(ASSERT_QUIET_EVAL, FALSE);
+
+// Set assertion handler
assert_options(ASSERT_CALLBACK , '__assertHandler');
// [EOF]
* @throws NullPointerException If listenerInstance is NULL
*/
function discoverSocket (array $packageData, $connectionType);
+
+ /**
+ * Tries to dicover the right listener instance
+ *
+ * @param $protocolInstance An instance of a HandleableProtocol class
+ * @param $packageData Raw package data
+ * @return $listenerInstance An instance of a Listenable instance or null
+ */
+ function discoverListenerInstance (HandleableProtocol $protocolInstance, array $packageData);
}
// [EOF]
* @param $method Value of __METHOD__ from calling method
* @param $line Value of __LINE__ from calling method
* @param $socketResource A valid socket resource
- * @param $recipientData An array with two elements: 0=IP number, 1=port number
+ * @param $unlData A valid UNL data array
* @return void
* @throws InvalidSocketException If $socketResource is no socket resource
* @throws NoSocketErrorDetectedException If socket_last_error() gives zero back
*/
- protected final function handleSocketError ($method, $line, $socketResource, array $recipientData) {
+ protected final function handleSocketError ($method, $line, $socketResource, array $unlData) {
// This method handles only socket resources
if (!is_resource($socketResource)) {
// No resource, abort here
throw new InvalidSocketException(array($this, $socketResource), BaseListener::EXCEPTION_INVALID_SOCKET);
} // END - if
- // Check count of array, should be two
- assert(count($recipientData) == 2);
+ // Check UNL array
+ //* DEBUG-DIE: */ die(__METHOD__ . ':unlData=' . print_r($unlData, TRUE));
+ assert(isset($unlData[UniversalNodeLocator::UNL_PART_PROTOCOL]));
+ assert(isset($unlData[UniversalNodeLocator::UNL_PART_ADDRESS]));
+ assert(isset($unlData[UniversalNodeLocator::UNL_PART_PORT]));
// Get error code for first validation (0 is not an error)
$errorCode = socket_last_error($socketResource);
$handlerName = $this->getSocketErrorHandlerFromCode($errorCode);
// Call-back the error handler method
- call_user_func_array(array($this, $handlerName), array($socketResource, $recipientData));
+ call_user_func_array(array($this, $handlerName), array($socketResource, $unlData));
// Finally clear the error because it has been handled
socket_clear_error($socketResource);
/**
* Tries to dicover the right listener instance
*
- * @param $protocolName Protocol name
+ * @param $protocolInstance An instance of a HandleableProtocol class
* @param $packageData Raw package data
* @return $listenerInstance An instance of a Listenable instance or null
*/
- public function discoverListenerInstance ($protocolName, array $packageData) {
+ public function discoverListenerInstance (HandleableProtocol $protocolInstance, array $packageData) {
// Debug message
- //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('SOCKET-DISCOVERY[' . __METHOD__ . ':' . __LINE__ . ']: protocolName=' . $protocolName . ' - ENTERED!');
+ /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('SOCKET-DISCOVERY[' . __METHOD__ . ':' . __LINE__ . ']: protocolInstance=' . $protocolInstance->__toString() . ' - ENTERED!');
/*
* Get the listener pool instance, we need to lookup the matching
// Init listener instance
$listenerInstance = NULL;
+ // Get handler name
+ $protocolName = $protocolInstance->getProtocolName();
+
+ // Debug message
+ /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('SOCKET-DISCOVERY[' . __METHOD__ . ':' . __LINE__ . ']: protocolName=' . $protocolName . ',poolEntriesInstance=' . $poolInstance->getPoolEntriesInstance()->__toString());
+
/*
* Now we need to choose again. It is whether 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) {
+ foreach ($poolInstance->getPoolEntriesInstance()->getArrayFromList($protocolName) as $listenerInstance) {
// Debug output
- //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('SOCKET-DISCOVERY[' . __METHOD__ . ':' . __LINE__ . ']: protocolName=' . $protocolName . ',listenerInstance=' . $listenerInstance->__toString());
+ /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('SOCKET-DISCOVERY[' . __METHOD__ . ':' . __LINE__ . ']: protocolName=' . $protocolName . ',listenerInstance[' . gettype($listenerInstance) . ']=' . $listenerInstance);
+
+ // Make sure the instance is valid
+ assert($listenerInstance instanceof Listenable);
// Does the listener want that package?
if ($listenerInstance->ifListenerAcceptsPackageData($packageData)) {
// Not valid, throw exception
throw new InvalidUnlException(array($this, $protocolInstance, $packageData), BaseHubSystem::EXCEPTION_INVALID_UNL);
} // END - if
- die(__METHOD__ . ':protocolInstance=' . $protocolInstance . ',packageData=' . print_r($packageData, TRUE));
// Get the listener instance
$listenerInstance = $this->discoverListenerInstance($protocolInstance, $packageData);
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
class BaseProtocolHandler extends BaseHandler {
+ /**
+ * Whole UNL data array
+ */
+ private $universalNodeLocatorData = array();
+
/**
* Protected constructor
*
parent::__construct($className);
}
+ /**
+ * Setter for UNL data array to satify HandleableProtocol
+ *
+ * @para $unlData The UNL data array
+ * @return void
+ */
+ protected final function setUniversalNodeLocatorData (array $unlData) {
+ // Set new UNL data array
+ $this->universalNodeLocatorData = $unlData;
+ }
+
+ /**
+ * Getter for UNL data array to satify HandleableProtocol
+ *
+ * @return $unlData The UNL data array
+ */
+ public final function getUniversalNodeLocatorData () {
+ // Return UNL data array
+ return $this->universalNodeLocatorData;
+ }
+
/**
* Validates given UNL very basicly by given regular expression. You
* normally don't need/want to overwrite this method as this is a very basic
* validation only based on a regex.
*
* @param $unl Universal Node Locator to validate
- * @param $regex Regular expression to use for validation without slashes
* @return $isValid Whether the UNL is valid
*/
- protected final function isValidUniversalNodeLocator ($unl, $regex) {
+ protected final function isValidUniversalNodeLocator ($unl) {
// Debug message
//* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('[' . __METHOD__ . ':' . __LINE__ . ']: unl=' . $unl . ',regex=' . $regex . ' - CALLED!');
// Very basic regex check
- $isValid = (preg_match('/^' . $regex . '$/', $unl) === 1);
+ $isValid = (preg_match($this->getRegularExpression(), $unl) === 1);
// Return result
//* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('[' . __METHOD__ . ':' . __LINE__ . ']: isValid=' . intval($isValid) . ' - EXIT!');
return $isValid;
}
+
+ /**
+ * Parses the given UNL by splitting it up in its components. The UNL ...
+ *
+ * protocol://address[:port]
+ *
+ * ... becomes:
+ *
+ * array(
+ * 'protocol' => 'value',
+ * 'address' => 'value',
+ * 'extra' => 'port'
+ * )
+ *
+ * The value for 'extra' then must be handled by parseUniversalNodeLocator()
+ * of the individual protocol handler as this is protocol-specific.
+ *
+ * @param $unl Universal Node Locator (UNL) to "parse"
+ * @return $unlData Array with all components of the UNL
+ */
+ protected function parseGenericUniversalNodeLocator ($unl) {
+ // Debug message
+ //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('[' . __METHOD__ . ':' . __LINE__ . ']: unl=' . $unl . ' - CALLED!');
+
+ // Make sure the UNL is valid
+ assert($this->isValidUniversalNodeLocator($unl));
+
+ /*
+ * "Parse" the UNL "generically", sadly this cannot be done by using preg_match() :-(
+ * @TODO If you know why, please fix and explain it to me.
+ */
+ $unlParts = explode('://', $unl);
+
+ // Split again the last part as: address:port
+ $unlParts[1] = explode(':', $unlParts[1]);
+
+ // Now there is an almost useable array which then can be copied to the "real" array.
+ $unlData = array(
+ UniversalNodeLocator::UNL_PART_PROTOCOL => $unlParts[0],
+ UniversalNodeLocator::UNL_PART_ADDRESS => $unlParts[1][0],
+ UniversalNodeLocator::UNL_PART_EXTRA => $unlParts[1][1]
+ );
+
+ // Debug message
+ //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('[' . __METHOD__ . ':' . __LINE__ . ']: unlData=' . print_r($unlData, TRUE) . ' - EXIT!');
+
+ // Return the generic array
+ return $unlData;
+ }
}
// [EOF]
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
class BaseIpV4ProtocolHandler extends BaseProtocolHandler {
+ // Regular expression for validating IP:port UNLs
+ const UNL_REGEX = '/^([a-z]{1,}):\/\/\b(([01]?\d?\d|2[0-4]\d|25[0-5])\.){3}([01]?\d?\d|2[0-4]\d|25[0-5])\b:(6553[0-5]|655[0-2][0-9]\d|65[0-4](\d){2}|6[0-4](\d){3}|[1-5](\d){4}|[1-9](\d){0,3})$/';
+
/**
* Port number
*/
private $port = 0;
- // Regular expression for validating IP:port UNLs
- const UNL_REGEX = '([a-z]{1,}):\/\/\b(([01]?\d?\d|2[0-4]\d|25[0-5])\.){3}([01]?\d?\d|2[0-4]\d|25[0-5])\b:(6553[0-5]|655[0-2][0-9]\d|65[0-4](\d){2}|6[0-4](\d){3}|[1-5](\d){4}|[1-9](\d){0,3})';
-
/**
* Protected constructor
*
protected function __construct ($className) {
// Call parent constructor
parent::__construct($className);
+
+ // Set regex
+ $this->setRegularExpression(self::UNL_REGEX);
}
/**
return $this->port;
}
+ /**
+ * Parses the given UNL by splitting it up in its components. The UNL ...
+ *
+ * protocol://address[:port]
+ *
+ * ... becomes:
+ *
+ * array(
+ * 'protocol' => 'value',
+ * 'address' => 'value',
+ * 'port' => 123
+ * )
+ *
+ * @param $unl Universal Node Locator (UNL) to "parse"
+ * @return $unlData Array with all components of the UNL
+ */
+ protected function parseUniversalNodeLocator ($unl) {
+ // Debug message
+ //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('[' . __METHOD__ . ':' . __LINE__ . ']: unl=' . $unl . ' - CALLED!');
+
+ // First generic parse
+ $unlData = parent::parseGenericUniversalNodeLocator($unl);
+
+ /*
+ * Make sure the generic parts are all there. In case of a rewrite,
+ * these assertitions will bail out on badly formed arrays.
+ */
+ assert(isset($unlData[UniversalNodeLocator::UNL_PART_PROTOCOL]));
+ assert(isset($unlData[UniversalNodeLocator::UNL_PART_ADDRESS]));
+ assert(isset($unlData[UniversalNodeLocator::UNL_PART_EXTRA]));
+
+ // Copy 'extra' -> 'port' ...
+ $unlData[UniversalNodeLocator::UNL_PART_PORT] = $unlData[UniversalNodeLocator::UNL_PART_EXTRA];
+
+ // ... and drop 'extra'
+ unset($unlData[UniversalNodeLocator::UNL_PART_EXTRA]);
+
+ // Debug message
+ //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('[' . __METHOD__ . ':' . __LINE__ . ']: unlData=' . print_r($unlData, TRUE) . ' - EXIT!');
+ return $unlData;
+ }
+
/**
* Validates given 'recipient' if it is a valid UNL. This means that the UNL
* can be parsed by the protocol handler.
*/
public function isValidUniversalNodeLocatorByPackageData (array $packageData) {
// Debug message
- /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('[' . __METHOD__ . ':' . __LINE__ . ']: CALLED!');
+ //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('[' . __METHOD__ . ':' . __LINE__ . ']: CALLED!');
// Is 'recipient' there?
assert(isset($packageData[NetworkPackage::PACKAGE_DATA_RECIPIENT]));
assert(substr($packageData[NetworkPackage::PACKAGE_DATA_RECIPIENT], 0, strlen($this->getHandlerName())) != $this->getHandlerName());
// Default is from generic validation
- $isValid = $this->isValidUniversalNodeLocator($packageData[NetworkPackage::PACKAGE_DATA_RECIPIENT], self::UNL_REGEX);
+ $isValid = $this->isValidUniversalNodeLocator($packageData[NetworkPackage::PACKAGE_DATA_RECIPIENT]);
// Debug message
- /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('[' . __METHOD__ . ':' . __LINE__ . ']: PACKAGE_DATA_RECIPIENT=' . $packageData[NetworkPackage::PACKAGE_DATA_RECIPIENT] . ',isValid[' . gettype($isValid) . ']=' . intval($isValid));
+ //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('[' . __METHOD__ . ':' . __LINE__ . ']: PACKAGE_DATA_RECIPIENT=' . $packageData[NetworkPackage::PACKAGE_DATA_RECIPIENT] . ',isValid[' . gettype($isValid) . ']=' . intval($isValid));
// If this doesn't fail, continue validating the IP:port combination
if ($isValid === TRUE) {
- // Okay, the basic test is passed, so reset the variable
- $isValid = FALSE;
-
// ... and validate IP:port, first "parse" the UNL
- $unlParts = $this->parseUniversalNodeLocator($packageData[NetworkPackage::PACKAGE_DATA_RECIPIENT]);
+ $unlData = $this->parseUniversalNodeLocator($packageData[NetworkPackage::PACKAGE_DATA_RECIPIENT]);
+
+ /*
+ * Make sure the extra field 'port' is there. This may look
+ * superflious but in case of a rewrite this assert will stop at
+ * badly formated arrays.
+ */
+ assert(isset($unlData[UniversalNodeLocator::UNL_PART_PORT]));
+
+ // Set whole UNL data array
+ $this->setUniversalNodeLocatorData($unlData);
- // Debug die
- die(__METHOD__ . ':PACKAGE_DATA_RECIPIENT=' . $packageData[NetworkPackage::PACKAGE_DATA_RECIPIENT] . ',unlParts=' . print_r($unlParts, TRUE) . PHP_EOL);
+ // Set port
+ $this->setPort($unlData[UniversalNodeLocator::UNL_PART_PORT]);
} // END - if
// Return result
- /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('[' . __METHOD__ . ':' . __LINE__ . ']: isValid=' . intval($isValid) . ' - EXIT!');
+ //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('[' . __METHOD__ . ':' . __LINE__ . ']: isValid=' . intval($isValid) . ' - EXIT!');
return $isValid;
}
}
// Call parent constructor
parent::__construct(__CLASS__);
- // Set handler name
+ // Set handler and protocol type
$this->setHandlerName('tcp_protocol');
+ $this->setProtocolName('tcp');
}
/**
*/
private function unregisterTask (array $taskData) {
// Debug output
- self::createDebugInstance(__CLASS__)->debugOutput('TASK-HANDLER[' . __METHOD__ . ':' . __LINE__ . ']: Removing task ' . $taskData['id'] . ' from queue - START');
+ self::createDebugInstance(__CLASS__)->debugOutput('TASK-HANDLER[' . __METHOD__ . ':' . __LINE__ . ']: Removing task ' . $taskData['id'] . ' from queue - CALLED!');
// Remove the entry
$this->getListInstance()->removeEntry('tasks', $taskData);
// Debug output
- self::createDebugInstance(__CLASS__)->debugOutput('TASK-HANDLER[' . __METHOD__ . ':' . __LINE__ . ']: Removing task ' . $taskData['id'] . ' from queue - FINISHED');
+ self::createDebugInstance(__CLASS__)->debugOutput('TASK-HANDLER[' . __METHOD__ . ':' . __LINE__ . ']: Removing task ' . $taskData['id'] . ' from queue - EXIT!');
}
/**
*/
private $connectionType = 'invalid';
- /**
- * Port number used
- */
- private $connectionPort = 0;
-
/**
* (IP) Adress used
*/
$this->connectionType = $connectionType;
}
- /**
- * Getter for port number to satify HandleableProtocol
- *
- * @return $connectionPort The port number
- */
- public final function getConnectionPort () {
- return $this->connectionPort;
- }
-
- /**
- * Setter for port number to satify HandleableProtocol
- *
- * @param $connectionPort The port number
- * @return void
- */
- protected final function setConenctionPort ($connectionPort) {
- $this->connectionPort = $connectionPort;
- }
-
/**
* Getter for IP address
*
}
/**
- * Initializes the current connection
+ * Setter for isInitialized
*
+ * @param $isInitialized Name of used protocol in this connection
* @return void
- * @throws SocketOptionException If setting any socket option fails
*/
- protected function initConnection () {
- // Get socket resource
- $socketResource = $this->getSocketResource();
-
- // Set the option to reuse the port
- if (!socket_set_option($socketResource, SOL_SOCKET, SO_REUSEADDR, 1)) {
- // Handle this socket error with a faked recipientData array
- $this->handleSocketError(__METHOD__, __LINE__, $socketResource, array('0.0.0.0', '0'));
-
- // And throw again
- // @TODO Move this to the socket error handler
- throw new SocketOptionException(array($this, $socketResource, $socketError, $errorMessage), BaseListener::EXCEPTION_INVALID_SOCKET);
- } // END - if
-
- /*
- * Set socket to non-blocking mode before trying to establish a link to
- * it. This is now the default behaviour for all connection helpers who
- * call initConnection(); .
- */
- if (!socket_set_nonblock($socketResource)) {
- // Handle this socket error with a faked recipientData array
- $helperInstance->handleSocketError(__METHOD__, __LINE__, $socketResource, array('0.0.0.0', '0'));
-
- // And throw again
- throw new SocketOptionException(array($helperInstance, $socketResource, $socketError, $errorMessage), BaseListener::EXCEPTION_INVALID_SOCKET);
- } // END - if
-
- // Last step: mark connection as initialized
- $this->isInitialized = TRUE;
+ protected final function setIsInitialized ($isInitialized) {
+ $this->isInitialized = $isInitialized;
}
/**
- * Attempts to connect to a peer by given IP number and port from a valid
- * recipientData array with currently configured timeout.
+ * Getter for isInitialized (NOTE: no 'get' prefix for boolean attributes!)
*
- * @param $recipientData A valid recipient data array, 0=IP; 1=PORT
- * @return $isConnected Whether the connection went fine
- * @see Please see http://de.php.net/manual/en/function.socket-connect.php#84465 for original code
- * @todo Rewrite the while() loop to a iterator to not let the software stay very long here
+ * @return $isInitialized Name of used protocol in this connection
*/
- protected function connectToPeerByRecipientData (array $recipientData) {
- // Only call this if the connection is initialized by initConnection()
- assert($this->isInitialized === TRUE);
-
- // Get current time
- $time = time();
-
- // "Cache" socket resource and timeout config
- $socketResource = $this->getSocketResource();
- $timeout = $this->getConfigInstance()->getConfigEntry('socket_timeout_seconds');
-
- // Debug output
- self::createDebugInstance(__CLASS__)->debugOutput('CONNECTION-HELPER[' . __METHOD__ . ':' . __LINE__ . ']: Trying to connect to ' . $recipientData[0] . ':' . $recipientData[1] . ' with socketResource[' . gettype($socketResource) . ']=' . $socketResource . ' ...');
-
- // Try to connect until it is connected
- while ($isConnected = !@socket_connect($socketResource, $recipientData[0], $recipientData[1])) {
- // Get last socket error
- $socketError = socket_last_error($socketResource);
-
- // Skip any errors which may happen on non-blocking connections
- if (($socketError == SOCKET_EINPROGRESS) || ($socketError == SOCKET_EALREADY)) {
- // Now, is that attempt within parameters?
- if ((time() - $time) >= $timeout) {
- // Didn't work within timeout
- $isConnected = FALSE;
- break;
- } // END - if
-
- // Sleep about one second
- $this->idle(1000);
- } elseif ($socketError != 0) {
- // Stop on everything else pronto
- $isConnected = FALSE;
- break;
- }
- } // END - while
-
- // Is the peer connected?
- if ($isConnected === TRUE) {
- // Connection is fully established here, so change the state.
- PeerStateFactory::createPeerStateInstanceByName('connected', $this);
- } else {
- /*
- * There was a problem connecting to the peer (this state is a meta
- * state until the error handler has found the real cause).
- */
- PeerStateFactory::createPeerStateInstanceByName('problem', $this);
- }
-
- // Return status
- return $isConnected;
+ protected final function isInitialized () {
+ return $this->isInitialized;
}
/**
$this->getPackageInstance()->getStackInstance()->pushNamed(NetworkPackage::STACKER_NAME_OUTGOING_STREAM, $encodedDataArray);
}
- /**
- * Marks this connection as shutted down
- *
- * @return void
- */
- protected final function markConnectionShuttedDown () {
- //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('CONNECTION-HELPER[' . __METHOD__ . ':' . __LINE__ . ']: ' . $this->__toString() . ' has been marked as shutted down');
- $this->shuttedDown = TRUE;
-
- // And remove the (now invalid) socket
- $this->setSocketResource(FALSE);
- }
-
/**
* Getter for shuttedDown
*
//* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('CONNECTION-HELPER[' . __METHOD__ . ':' . __LINE__ . ']: ' . $this->__toString() . ',shuttedDown=' . intval($this->shuttedDown));
return $this->shuttedDown;
}
-
- // ************************************************************************
- // Socket error handler call-back methods
- // ************************************************************************
-
- /**
- * Handles socket error 'connection timed out', but does not clear it for
- * later debugging purposes.
- *
- * @param $socketResource A valid socket resource
- * @param $recipientData An array with two elements: 0=IP number, 1=port number
- * @return void
- * @throws SocketConnectionException The connection attempts fails with a time-out
- */
- protected function socketErrorConnectionTimedOutHandler ($socketResource, array $recipientData) {
- // Get socket error code for verification
- $socketError = socket_last_error($socketResource);
-
- // Get error message
- $errorMessage = socket_strerror($socketError);
-
- // Shutdown this socket
- $this->shutdownSocket($socketResource);
-
- // Throw it again
- throw new SocketConnectionException(array($this, $socketResource, $socketError, $errorMessage), BaseListener::EXCEPTION_INVALID_SOCKET);
- }
-
- /**
- * Handles socket error 'resource temporary unavailable', but does not
- * clear it for later debugging purposes.
- *
- * @param $socketResource A valid socket resource
- * @param $recipientData An array with two elements: 0=IP number, 1=port number
- * @return void
- * @throws SocketConnectionException The connection attempts fails with a time-out
- */
- protected function socketErrorResourceUnavailableHandler ($socketResource, array $recipientData) {
- // Get socket error code for verification
- $socketError = socket_last_error($socketResource);
-
- // Get error message
- $errorMessage = socket_strerror($socketError);
-
- // Shutdown this socket
- $this->shutdownSocket($socketResource);
-
- // Throw it again
- throw new SocketConnectionException(array($this, $socketResource, $socketError, $errorMessage), BaseListener::EXCEPTION_INVALID_SOCKET);
- }
-
- /**
- * Handles socket error 'connection refused', but does not clear it for
- * later debugging purposes.
- *
- * @param $socketResource A valid socket resource
- * @param $recipientData An array with two elements: 0=IP number, 1=port number
- * @return void
- * @throws SocketConnectionException The connection attempts fails with a time-out
- */
- protected function socketErrorConnectionRefusedHandler ($socketResource, array $recipientData) {
- // Get socket error code for verification
- $socketError = socket_last_error($socketResource);
-
- // Get error message
- $errorMessage = socket_strerror($socketError);
-
- // Shutdown this socket
- $this->shutdownSocket($socketResource);
-
- // Throw it again
- throw new SocketConnectionException(array($this, $socketResource, $socketError, $errorMessage), BaseListener::EXCEPTION_INVALID_SOCKET);
- }
-
- /**
- * Handles socket error 'no route to host', but does not clear it for later
- * debugging purposes.
- *
- * @param $socketResource A valid socket resource
- * @param $recipientData An array with two elements: 0=IP number, 1=port number
- * @return void
- * @throws SocketConnectionException The connection attempts fails with a time-out
- */
- protected function socketErrorNoRouteToHostHandler ($socketResource, array $recipientData) {
- // Get socket error code for verification
- $socketError = socket_last_error($socketResource);
-
- // Get error message
- $errorMessage = socket_strerror($socketError);
-
- // Shutdown this socket
- $this->shutdownSocket($socketResource);
-
- // Throw it again
- throw new SocketConnectionException(array($this, $socketResource, $socketError, $errorMessage), BaseListener::EXCEPTION_INVALID_SOCKET);
- }
-
- /**
- * Handles socket error 'operation already in progress' which happens in
- * method connectToPeerByRecipientData() on timed out connection
- * attempts.
- *
- * @param $socketResource A valid socket resource
- * @param $recipientData An array with two elements: 0=IP number, 1=port number
- * @return void
- * @throws SocketConnectionException The connection attempts fails with a time-out
- */
- protected function socketErrorOperationAlreadyProgressHandler ($socketResource, array $recipientData) {
- // Get socket error code for verification
- $socketError = socket_last_error($socketResource);
-
- // Get error message
- $errorMessage = socket_strerror($socketError);
-
- // Half-shutdown this socket (see there for difference to shutdownSocket())
- $this->halfShutdownSocket($socketResource);
-
- // Throw it again
- throw new SocketConnectionException(array($this, $socketResource, $socketError, $errorMessage), BaseListener::EXCEPTION_INVALID_SOCKET);
- }
-
- /**
- * Handles socket error 'connection reset by peer', but does not clear it for
- * later debugging purposes.
- *
- * @param $socketResource A valid socket resource
- * @param $recipientData An array with two elements: 0=IP number, 1=port number
- * @return void
- * @throws SocketConnectionException The connection attempts fails with a time-out
- */
- protected function socketErrorConnectionResetByPeerHandler ($socketResource, array $recipientData) {
- // Get socket error code for verification
- $socketError = socket_last_error($socketResource);
-
- // Get error message
- $errorMessage = socket_strerror($socketError);
-
- // Shutdown this socket
- $this->shutdownSocket($socketResource);
-
- // Throw it again
- throw new SocketConnectionException(array($this, $socketResource, $socketError, $errorMessage), BaseListener::EXCEPTION_INVALID_SOCKET);
- }
-
- /**
- * Handles socket "error" 'operation now in progress' which can be safely
- * passed on with non-blocking connections.
- *
- * @param $socketResource A valid socket resource
- * @param $recipientData An array with two elements: 0=IP number, 1=port number
- * @return void
- */
- protected function socketErrorOperationInProgressHandler ($socketResource, array $recipientData) {
- self::createDebugInstance(__CLASS__)->debugOutput('CONNECTION-HELPER[' . __METHOD__ . ':' . __LINE__ . ']: Operation is now in progress, this is usual for non-blocking connections and is no bug.');
- }
}
// [EOF]
--- /dev/null
+Deny from all
--- /dev/null
+<?php
+/**
+ * A ??? connection helper class
+ *
+ * @author Roland Haeder <webmaster@ship-simu.org>
+ * @version 0.0.0
+ * @copyright Copyright (c) 2007, 2008 Roland Haeder, 2009 - 2014 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 <http://www.gnu.org/licenses/>.
+ */
+class BaseIpV4ConnectionHelper extends BaseConnectionHelper {
+ /**
+ * Port number used
+ */
+ private $connectionPort = 0;
+
+ /**
+ * Protected constructor
+ *
+ * @return void
+ */
+ protected function __construct () {
+ // Call parent constructor
+ parent::__construct(__CLASS__);
+ }
+
+ /**
+ * Getter for port number to satify HandleableProtocol
+ *
+ * @return $connectionPort The port number
+ */
+ public final function getConnectionPort () {
+ return $this->connectionPort;
+ }
+
+ /**
+ * Setter for port number to satify HandleableProtocol
+ *
+ * @param $connectionPort The port number
+ * @return void
+ */
+ protected final function setConnectionPort ($connectionPort) {
+ $this->connectionPort = $connectionPort;
+ }
+
+ /**
+ * Initializes the current connection
+ *
+ * @return void
+ * @throws SocketOptionException If setting any socket option fails
+ */
+ protected function initConnection () {
+ // Get socket resource
+ $socketResource = $this->getSocketResource();
+
+ // Set the option to reuse the port
+ if (!socket_set_option($socketResource, SOL_SOCKET, SO_REUSEADDR, 1)) {
+ // Handle this socket error with a faked recipientData array
+ $this->handleSocketError(__METHOD__, __LINE__, $socketResource, array('0.0.0.0', '0'));
+
+ // And throw again
+ // @TODO Move this to the socket error handler
+ throw new SocketOptionException(array($this, $socketResource, $socketError, $errorMessage), BaseListener::EXCEPTION_INVALID_SOCKET);
+ } // END - if
+
+ /*
+ * Set socket to non-blocking mode before trying to establish a link to
+ * it. This is now the default behaviour for all connection helpers who
+ * call initConnection(); .
+ */
+ if (!socket_set_nonblock($socketResource)) {
+ // Handle this socket error with a faked recipientData array
+ $helperInstance->handleSocketError(__METHOD__, __LINE__, $socketResource, array('0.0.0.0', '0'));
+
+ // And throw again
+ throw new SocketOptionException(array($helperInstance, $socketResource, $socketError, $errorMessage), BaseListener::EXCEPTION_INVALID_SOCKET);
+ } // END - if
+
+ // Last step: mark connection as initialized
+ $this->setIsInitialized(TRUE);
+ }
+
+ /**
+ * Attempts to connect to a peer by given IP number and port from a valid
+ * unlData array with currently configured timeout.
+ *
+ * @param $unlData Valid UNL data array
+ * @return $isConnected Whether the connection went fine
+ * @see Please see http://de.php.net/manual/en/function.socket-connect.php#84465 for original code
+ * @todo Rewrite the while() loop to a iterator to not let the software stay very long here
+ */
+ protected function connectToPeerByUnlData (array $unlData) {
+ // Only call this if the connection is initialized by initConnection()
+ assert($this->isInitialized());
+
+ // Is unlData complete?
+ assert(isset($unlData[UniversalNodeLocator::UNL_PART_PROTOCOL]));
+ assert(isset($unlData[UniversalNodeLocator::UNL_PART_ADDRESS]));
+ assert(isset($unlData[UniversalNodeLocator::UNL_PART_PORT]));
+
+ // Get current time
+ $time = time();
+
+ // "Cache" socket resource and timeout config
+ $socketResource = $this->getSocketResource();
+ $timeout = $this->getConfigInstance()->getConfigEntry('socket_timeout_seconds');
+
+ // Debug output
+ self::createDebugInstance(__CLASS__)->debugOutput('CONNECTION-HELPER[' . __METHOD__ . ':' . __LINE__ . ']: Trying to connect to ' . $unlData[UniversalNodeLocator::UNL_PART_ADDRESS] . ':' . $unlData[UniversalNodeLocator::UNL_PART_PORT] . ' with socketResource[' . gettype($socketResource) . ']=' . $socketResource . ' ...');
+
+ // Try to connect until it is connected
+ while ($isConnected = !@socket_connect($socketResource, $unlData[UniversalNodeLocator::UNL_PART_ADDRESS], $unlData[UniversalNodeLocator::UNL_PART_PORT])) {
+ // Get last socket error
+ $socketError = socket_last_error($socketResource);
+
+ // Skip any errors which may happen on non-blocking connections
+ if (($socketError == SOCKET_EINPROGRESS) || ($socketError == SOCKET_EALREADY)) {
+ // Now, is that attempt within parameters?
+ if ((time() - $time) >= $timeout) {
+ // Didn't work within timeout
+ $isConnected = FALSE;
+ break;
+ } // END - if
+
+ // Sleep about one second
+ $this->idle(1000);
+ } elseif ($socketError != 0) {
+ // Stop on everything else pronto
+ $isConnected = FALSE;
+ break;
+ }
+ } // END - while
+
+ // Is the peer connected?
+ if ($isConnected === TRUE) {
+ // Connection is fully established here, so change the state.
+ PeerStateFactory::createPeerStateInstanceByName('connected', $this);
+ } else {
+ /*
+ * There was a problem connecting to the peer (this state is a meta
+ * state until the error handler has found the real cause).
+ */
+ PeerStateFactory::createPeerStateInstanceByName('problem', $this);
+ }
+
+ // Return status
+ return $isConnected;
+ }
+
+ /**
+ * Marks this connection as shutted down
+ *
+ * @return void
+ */
+ protected final function markConnectionShuttedDown () {
+ //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('CONNECTION-HELPER[' . __METHOD__ . ':' . __LINE__ . ']: ' . $this->__toString() . ' has been marked as shutted down');
+ $this->shuttedDown = TRUE;
+
+ // And remove the (now invalid) socket
+ $this->setSocketResource(FALSE);
+ }
+
+ // ************************************************************************
+ // Socket error handler call-back methods
+ // ************************************************************************
+
+ /**
+ * Handles socket error 'connection timed out', but does not clear it for
+ * later debugging purposes.
+ *
+ * @param $socketResource A valid socket resource
+ * @param $unlData A valid UNL data array
+ * @return void
+ * @throws SocketConnectionException The connection attempts fails with a time-out
+ */
+ protected function socketErrorConnectionTimedOutHandler ($socketResource, array $unlData) {
+ // Get socket error code for verification
+ $socketError = socket_last_error($socketResource);
+
+ // Get error message
+ $errorMessage = socket_strerror($socketError);
+
+ // Shutdown this socket
+ $this->shutdownSocket($socketResource);
+
+ // Throw it again
+ throw new SocketConnectionException(array($this, $socketResource, $socketError, $errorMessage), BaseListener::EXCEPTION_INVALID_SOCKET);
+ }
+
+ /**
+ * Handles socket error 'resource temporary unavailable', but does not
+ * clear it for later debugging purposes.
+ *
+ * @param $socketResource A valid socket resource
+ * @param $unlData A valid UNL data array
+ * @return void
+ * @throws SocketConnectionException The connection attempts fails with a time-out
+ */
+ protected function socketErrorResourceUnavailableHandler ($socketResource, array $unlData) {
+ // Get socket error code for verification
+ $socketError = socket_last_error($socketResource);
+
+ // Get error message
+ $errorMessage = socket_strerror($socketError);
+
+ // Shutdown this socket
+ $this->shutdownSocket($socketResource);
+
+ // Throw it again
+ throw new SocketConnectionException(array($this, $socketResource, $socketError, $errorMessage), BaseListener::EXCEPTION_INVALID_SOCKET);
+ }
+
+ /**
+ * Handles socket error 'connection refused', but does not clear it for
+ * later debugging purposes.
+ *
+ * @param $socketResource A valid socket resource
+ * @param $unlData A valid UNL data array
+ * @return void
+ * @throws SocketConnectionException The connection attempts fails with a time-out
+ */
+ protected function socketErrorConnectionRefusedHandler ($socketResource, array $unlData) {
+ // Get socket error code for verification
+ $socketError = socket_last_error($socketResource);
+
+ // Get error message
+ $errorMessage = socket_strerror($socketError);
+
+ // Shutdown this socket
+ $this->shutdownSocket($socketResource);
+
+ // Throw it again
+ throw new SocketConnectionException(array($this, $socketResource, $socketError, $errorMessage), BaseListener::EXCEPTION_INVALID_SOCKET);
+ }
+
+ /**
+ * Handles socket error 'no route to host', but does not clear it for later
+ * debugging purposes.
+ *
+ * @param $socketResource A valid socket resource
+ * @param $unlData A valid UNL data array
+ * @return void
+ * @throws SocketConnectionException The connection attempts fails with a time-out
+ */
+ protected function socketErrorNoRouteToHostHandler ($socketResource, array $unlData) {
+ // Get socket error code for verification
+ $socketError = socket_last_error($socketResource);
+
+ // Get error message
+ $errorMessage = socket_strerror($socketError);
+
+ // Shutdown this socket
+ $this->shutdownSocket($socketResource);
+
+ // Throw it again
+ throw new SocketConnectionException(array($this, $socketResource, $socketError, $errorMessage), BaseListener::EXCEPTION_INVALID_SOCKET);
+ }
+
+ /**
+ * Handles socket error 'operation already in progress' which happens in
+ * method connectToPeerByUnlData() on timed out connection
+ * attempts.
+ *
+ * @param $socketResource A valid socket resource
+ * @param $unlData A valid UNL data array
+ * @return void
+ * @throws SocketConnectionException The connection attempts fails with a time-out
+ */
+ protected function socketErrorOperationAlreadyProgressHandler ($socketResource, array $unlData) {
+ // Get socket error code for verification
+ $socketError = socket_last_error($socketResource);
+
+ // Get error message
+ $errorMessage = socket_strerror($socketError);
+
+ // Half-shutdown this socket (see there for difference to shutdownSocket())
+ $this->halfShutdownSocket($socketResource);
+
+ // Throw it again
+ throw new SocketConnectionException(array($this, $socketResource, $socketError, $errorMessage), BaseListener::EXCEPTION_INVALID_SOCKET);
+ }
+
+ /**
+ * Handles socket error 'connection reset by peer', but does not clear it for
+ * later debugging purposes.
+ *
+ * @param $socketResource A valid socket resource
+ * @param $unlData A valid UNL data array
+ * @return void
+ * @throws SocketConnectionException The connection attempts fails with a time-out
+ */
+ protected function socketErrorConnectionResetByPeerHandler ($socketResource, array $unlData) {
+ // Get socket error code for verification
+ $socketError = socket_last_error($socketResource);
+
+ // Get error message
+ $errorMessage = socket_strerror($socketError);
+
+ // Shutdown this socket
+ $this->shutdownSocket($socketResource);
+
+ // Throw it again
+ throw new SocketConnectionException(array($this, $socketResource, $socketError, $errorMessage), BaseListener::EXCEPTION_INVALID_SOCKET);
+ }
+
+ /**
+ * Handles socket "error" 'operation now in progress' which can be safely
+ * passed on with non-blocking connections.
+ *
+ * @param $socketResource A valid socket resource
+ * @param $unlData A valid UNL data array
+ * @return void
+ */
+ protected function socketErrorOperationInProgressHandler ($socketResource, array $unlData) {
+ self::createDebugInstance(__CLASS__)->debugOutput('CONNECTION-HELPER[' . __METHOD__ . ':' . __LINE__ . ']: Operation is now in progress, this is usual for non-blocking connections and is no bug.');
+ }
+}
+
+// [EOF]
+?>
--- /dev/null
+Deny from all
--- /dev/null
+<?php
+/**
+ * A TCP connection helper class
+ *
+ * @author Roland Haeder <webmaster@shipsimu.org>
+ * @version 0.0.0
+ * @copyright Copyright (c) 2007, 2008 Roland Haeder, 2009 - 2014 Core Developer Team
+ * @license GNU GPL 3.0 or any newer version
+ * @link http://www.shipsimu.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 <http://www.gnu.org/licenses/>.
+ */
+class TcpConnectionHelper extends BaseIpV4ConnectionHelper implements ConnectionHelper {
+ /**
+ * Protected constructor
+ *
+ * @return void
+ */
+ protected function __construct () {
+ // Call parent constructor
+ parent::__construct(__CLASS__);
+
+ // Set protocol
+ $this->setProtocolName('tcp');
+ }
+
+ /**
+ * Creates a half-connected socket resource ("connection") for given
+ * recipient in package data. After you called this method you still need to
+ * connect to the other node.
+ *
+ * @param $packageData Raw package data
+ * @return $socketResource Socket resource
+ * @throws SocketCreationException If the socket could not be created
+ * @throws SocketOptionException If a socket option could not be set
+ * @throws SocketConnectionException If a connection could not be opened
+ * @todo $errorCode/-Message are now in handleSocketError()'s call-back methods
+ */
+ 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, calling handleSocketError() is not
+ * possible here because that method would throw an
+ * InvalidSocketException back.
+ */
+ throw new SocketCreationException(array($helperInstance, gettype($socketResource)), BaseListener::EXCEPTION_SOCKET_CREATION_FAILED);
+ } // END - if
+
+ // Get socket error code for verification
+ $socketError = socket_last_error($socketResource);
+
+ // Check if there was an error else
+ if ($socketError > 0) {
+ // Handle this socket error with a faked recipientData array
+ $helperInstance->handleSocketError(__METHOD__, __LINE__, $socketResource, array('0.0.0.0', '0'));
+
+ // Then throw again
+ throw new SocketCreationException(array($helperInstance, gettype($socketResource), $socketError, socket_strerror($socketError)), BaseListener::EXCEPTION_SOCKET_CREATION_FAILED);
+ } // END - if
+
+ // Debug message
+ //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('HELPER[' . __METHOD__ . ':' . __LINE__ . ']: Setting socket resource ... (' . gettype($socketResource) . ')');
+
+ // Set the resource
+ $helperInstance->setSocketResource($socketResource);
+
+ // Init connection
+ $helperInstance->initConnection();
+
+ // @TODO The whole resolving part should be moved out and made more configurable
+ // Init recipient data
+ $unlData = array();
+
+ // Try to solve the recipient
+ try {
+ // Resolve any session ids; 0 = IP, 1 = Port
+ $handlerInstance = ProtocolHandlerFactory::createProtocolHandlerFromPackageData($packageData);
+
+ // Get UNL data
+ $unlData = $handlerInstance->getUniversalNodeLocatorData();
+
+ // Set handler instance
+ $helperInstance->setHandlerInstance($handlerInstance);
+ } catch (NoValidHostnameException $e) {
+ // Debug message
+ self::createDebugInstance(__CLASS__)->debugOutput('CONNECTION-HELPER[' . __METHOD__ . ':' . __LINE__ . ']: Failed to resolve ' . $packageData[NetworkPackage::PACKAGE_DATA_RECIPIENT] . ':' . $e->getMessage());
+
+ // Is the recipient equal as configured IP
+ if (substr($packageData[NetworkPackage::PACKAGE_DATA_RECIPIENT], 0, strlen($helperInstance->getConfigInstance()->getConfigEntry('external_address'))) == $helperInstance->getConfigInstance()->getConfigEntry('external_address')) {
+ // This may connect to shipsimu.org and requests 'ip.php' which will return our external IP address
+ $unlData[UniversalNodeLocator::UNL_PART_ADDRESS] = HubTools::determineExternalAddress();
+
+ // Do we have ip:port match?
+ // @TODO Rewrite this test for UNLs
+ if (strpos($packageData[NetworkPackage::PACKAGE_DATA_RECIPIENT], ':') === FALSE) {
+ // No ip:port!
+ $helperInstance->debugInstance($packageData[NetworkPackage::PACKAGE_DATA_RECIPIENT] . ' does not contain ":". Please fix this.');
+ } // END - if
+
+ // "explode" the ip:port, so index 1 will be the port number
+ // @TODO Rewrite this test for UNLs
+ $recipientArray = explode(':', $packageData[NetworkPackage::PACKAGE_DATA_RECIPIENT]);
+
+ // Add the port
+ $unlData[UniversalNodeLocator::UNL_PART_PORT] = $recipientArray[UniversalNodeLocator::UNL_PART_PORT];
+ } else {
+ // It doesn't match, we need to take care of this later
+ $helperInstance->debugInstance($packageData[NetworkPackage::PACKAGE_DATA_RECIPIENT] . '!=' . $helperInstance->getConfigInstance()->getConfigEntry('external_address'));
+ }
+ }
+
+ // Set address and maybe port
+ $helperInstance->setAddress($unlData[UniversalNodeLocator::UNL_PART_ADDRESS]);
+ $helperInstance->setConnectionPort($unlData[UniversalNodeLocator::UNL_PART_PORT]);
+
+ // Now connect to it
+ if (!$helperInstance->connectToPeerByUnlData($unlData)) {
+ // Handle socket error
+ $helperInstance->handleSocketError(__METHOD__, __LINE__, $socketResource, $unlData);
+ } // END - if
+
+ // Okay, that should be it. Return it...
+ return $socketResource;
+ }
+
+ /**
+ * Do the shutdown sequence for this connection helper
+ *
+ * @return void
+ * @throws SocketShutdownException If the current socket could not be shut down
+ * @todo We may want to implement a filter for ease notification of other objects like our pool
+ */
+ public function doShutdown () {
+ // Debug message
+ self::createDebugInstance(__CLASS__)->debugOutput('HELPER[' . __METHOD__ . ':' . __LINE__ . ']: Shutting down socket resource ' . $this->getSocketResource());
+
+ // Clear any previous errors
+ socket_clear_error($this->getSocketResource());
+
+ // Call the shutdown function on the currently set socket
+ if (!socket_shutdown($this->getSocketResource())) {
+ // Could not shutdown socket, this is fine if e.g. the other side is not connected, so analyse it
+ if (socket_last_error($this->getSocketResource()) != 107) {
+ // Something bad happened while we shutdown a socket
+ throw new SocketShutdownException($this, BaseListener::EXCEPTION_INVALID_SOCKET);
+ } // END - if
+ } // END - if
+
+ // Try to make blocking IO for socket_close()
+ socket_set_block($this->getSocketResource());
+
+ // Drop all data (don't sent any on socket closure)
+ socket_set_option($this->getSocketResource(), SOL_SOCKET, SO_LINGER, array('l_onoff' => 1, 'l_linger' => 0));
+
+ // Finally close socket to free some resources
+ socket_close($this->getSocketResource());
+
+ // Mark this connection as shutted down
+ $this->markConnectionShuttedDown();
+ }
+}
+
+// [EOF]
+?>
--- /dev/null
+Deny from all
--- /dev/null
+<?php
+/**
+ * A UDP connection helper class
+ *
+ * @author Roland Haeder <webmaster@shipsimu.org>
+ * @version 0.0.0
+ * @copyright Copyright (c) 2007, 2008 Roland Haeder, 2009 - 2014 Core Developer Team
+ * @license GNU GPL 3.0 or any newer version
+ * @link http://www.shipsimu.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 <http://www.gnu.org/licenses/>.
+ */
+class UdpConnectionHelper extends BaseIpV4ConnectionHelper implements ConnectionHelper {
+ /**
+ * Protected constructor
+ *
+ * @return void
+ */
+ protected function __construct () {
+ // Call parent constructor
+ parent::__construct(__CLASS__);
+
+ // Set protocol
+ $this->setProtocolName('udp');
+ }
+
+ /**
+ * Creates a half-connected socket resource ("connection") for given
+ * recipient in package data. After you called this method you still need to
+ * connect to the other node.
+ *
+ * @param $packageData Raw package data
+ * @return $socketResource Socket resource
+ */
+ public static function createConnectionFromPackageData (array $packageData) {
+ $this->debugBackTrace('[' . __METHOD__ . ':' . __LINE__ . ']: Unfinished method, packageData[]=' . count($packageData));
+ }
+
+ /**
+ * Do the shutdown sequence for this connection helper
+ *
+ * @return void
+ * @throws SocketShutdownException If the current socket could not be shut down
+ * @todo Implement a filter for ease notification of other objects like the pool
+ */
+ public function doShutdown () {
+ $this->partialStub('Please implement this method.');
+ }
+}
+
+// [EOF]
+?>
+++ /dev/null
-Deny from all
+++ /dev/null
-<?php
-/**
- * A TCP connection helper class
- *
- * @author Roland Haeder <webmaster@shipsimu.org>
- * @version 0.0.0
- * @copyright Copyright (c) 2007, 2008 Roland Haeder, 2009 - 2014 Core Developer Team
- * @license GNU GPL 3.0 or any newer version
- * @link http://www.shipsimu.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 <http://www.gnu.org/licenses/>.
- */
-class TcpConnectionHelper extends BaseConnectionHelper implements ConnectionHelper {
- /**
- * Protected constructor
- *
- * @return void
- */
- protected function __construct () {
- // Call parent constructor
- parent::__construct(__CLASS__);
-
- // Set protocol
- $this->setProtocolName('tcp');
- }
-
- /**
- * Creates a half-connected socket resource ("connection") for given
- * recipient in package data. After you called this method you still need to
- * connect to the other node.
- *
- * @param $packageData Raw package data
- * @return $socketResource Socket resource
- * @throws SocketCreationException If the socket could not be created
- * @throws SocketOptionException If a socket option could not be set
- * @throws SocketConnectionException If a connection could not be opened
- * @todo $errorCode/-Message are now in handleSocketError()'s call-back methods
- */
- 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, calling handleSocketError() is not
- * possible here because that method would throw an
- * InvalidSocketException back.
- */
- throw new SocketCreationException(array($helperInstance, gettype($socketResource)), BaseListener::EXCEPTION_SOCKET_CREATION_FAILED);
- } // END - if
-
- // Get socket error code for verification
- $socketError = socket_last_error($socketResource);
-
- // Check if there was an error else
- if ($socketError > 0) {
- // Handle this socket error with a faked recipientData array
- $helperInstance->handleSocketError(__METHOD__, __LINE__, $socketResource, array('0.0.0.0', '0'));
-
- // Then throw again
- throw new SocketCreationException(array($helperInstance, gettype($socketResource), $socketError, socket_strerror($socketError)), BaseListener::EXCEPTION_SOCKET_CREATION_FAILED);
- } // END - if
-
- // Debug message
- //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('HELPER[' . __METHOD__ . ':' . __LINE__ . ']: Setting socket resource ... (' . gettype($socketResource) . ')');
-
- // Set the resource
- $helperInstance->setSocketResource($socketResource);
-
- // Init connection
- $helperInstance->initConnection();
-
- // @TODO The whole resolving part should be moved out and made more configurable
- // Init recipient data
- $recipientData = NULL;
-
- // Try to solve the recipient
- try {
- // Resolve any session ids; 0 = IP, 1 = Port
- $resolved = HubTools::resolveSessionId($packageData[NetworkPackage::PACKAGE_DATA_RECIPIENT]);
- die(__METHOD__ . 'resolved=' . print_r($resolved, TRUE));
-
- $recipientData = explode(':', $resolved);
- } catch (NoValidHostnameException $e) {
- // Debug message
- self::createDebugInstance(__CLASS__)->debugOutput('CONNECTION-HELPER[' . __METHOD__ . ':' . __LINE__ . ']: Failed to resolve ' . $packageData[NetworkPackage::PACKAGE_DATA_RECIPIENT] . ':' . $e->getMessage());
-
- // Is the recipient equal as configured IP
- if (substr($packageData[NetworkPackage::PACKAGE_DATA_RECIPIENT], 0, strlen($helperInstance->getConfigInstance()->getConfigEntry('external_address'))) == $helperInstance->getConfigInstance()->getConfigEntry('external_address')) {
- // This may connect to shipsimu.org and requests 'ip.php' which will return our external IP address
- $recipientData[0] = HubTools::determineExternalAddress();
-
- // Do we have ip:port match?
- // @TODO Rewrite this test for UNLs
- if (strpos($packageData[NetworkPackage::PACKAGE_DATA_RECIPIENT], ':') === FALSE) {
- // No ip:port!
- $helperInstance->debugInstance($packageData[NetworkPackage::PACKAGE_DATA_RECIPIENT] . ' does not contain ":". Please fix this.');
- } // END - if
-
- // "explode" the ip:port, so index 1 will be the port number
- // @TODO Rewrite this test for UNLs
- $recipientArray = explode(':', $packageData[NetworkPackage::PACKAGE_DATA_RECIPIENT]);
-
- // Add the port
- $recipientData[1] = $recipientArray[1];
- } else {
- // It doesn't match, we need to take care of this later
- $helperInstance->debugInstance($packageData[NetworkPackage::PACKAGE_DATA_RECIPIENT] . '!=' . $helperInstance->getConfigInstance()->getConfigEntry('external_address'));
- }
- }
-
- // Set address and maybe port
- $helperInstance->setAddress($recipientData[0]);
- $helperInstance->setConnectionPort($recipientData[1]);
-
- // Now connect to it
- if (!$helperInstance->connectToPeerByRecipientData($recipientData)) {
- // Handle socket error
- $helperInstance->handleSocketError(__METHOD__, __LINE__, $socketResource, $recipientData);
- } // END - if
-
- // Okay, that should be it. Return it...
- return $socketResource;
- }
-
- /**
- * Do the shutdown sequence for this connection helper
- *
- * @return void
- * @throws SocketShutdownException If the current socket could not be shut down
- * @todo We may want to implement a filter for ease notification of other objects like our pool
- */
- public function doShutdown () {
- // Debug message
- self::createDebugInstance(__CLASS__)->debugOutput('HELPER[' . __METHOD__ . ':' . __LINE__ . ']: Shutting down socket resource ' . $this->getSocketResource());
-
- // Clear any previous errors
- socket_clear_error($this->getSocketResource());
-
- // Call the shutdown function on the currently set socket
- if (!socket_shutdown($this->getSocketResource())) {
- // Could not shutdown socket, this is fine if e.g. the other side is not connected, so analyse it
- if (socket_last_error($this->getSocketResource()) != 107) {
- // Something bad happened while we shutdown a socket
- throw new SocketShutdownException($this, BaseListener::EXCEPTION_INVALID_SOCKET);
- } // END - if
- } // END - if
-
- // Try to make blocking IO for socket_close()
- socket_set_block($this->getSocketResource());
-
- // Drop all data (don't sent any on socket closure)
- socket_set_option($this->getSocketResource(), SOL_SOCKET, SO_LINGER, array('l_onoff' => 1, 'l_linger' => 0));
-
- // Finally close socket to free some resources
- socket_close($this->getSocketResource());
-
- // Mark this connection as shutted down
- $this->markConnectionShuttedDown();
- }
-}
-
-// [EOF]
-?>
+++ /dev/null
-Deny from all
+++ /dev/null
-<?php
-/**
- * A UDP connection helper class
- *
- * @author Roland Haeder <webmaster@shipsimu.org>
- * @version 0.0.0
- * @copyright Copyright (c) 2007, 2008 Roland Haeder, 2009 - 2014 Core Developer Team
- * @license GNU GPL 3.0 or any newer version
- * @link http://www.shipsimu.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 <http://www.gnu.org/licenses/>.
- */
-class UdpConnectionHelper extends BaseConnectionHelper implements ConnectionHelper {
- /**
- * Protected constructor
- *
- * @return void
- */
- protected function __construct () {
- // Call parent constructor
- parent::__construct(__CLASS__);
-
- // Set protocol
- $this->setProtocolName('udp');
- }
-
- /**
- * Creates a half-connected socket resource ("connection") for given
- * recipient in package data. After you called this method you still need to
- * connect to the other node.
- *
- * @param $packageData Raw package data
- * @return $socketResource Socket resource
- */
- public static function createConnectionFromPackageData (array $packageData) {
- $this->debugBackTrace('[' . __METHOD__ . ':' . __LINE__ . ']: Unfinished method, packageData[]=' . count($packageData));
- }
-
- /**
- * Do the shutdown sequence for this connection helper
- *
- * @return void
- * @throws SocketShutdownException If the current socket could not be shut down
- * @todo Implement a filter for ease notification of other objects like the pool
- */
- public function doShutdown () {
- $this->partialStub('Please implement this method.');
- }
-}
-
-// [EOF]
-?>
*/
public function accept (Visitor $visitorInstance) {
// Debug message
- //* DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput(strtoupper($this->getProtocolName()) . '-LISTENER[' . __METHOD__ . ':' . __LINE__ . ']: ' . $visitorInstance->__toString() . ' has visited ' . $this->__toString() . ' - START');
+ //* DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput(strtoupper($this->getProtocolName()) . '-LISTENER[' . __METHOD__ . ':' . __LINE__ . ']: ' . $visitorInstance->__toString() . ' has visited ' . $this->__toString() . ' - CALLED!');
// Visit this listener
$visitorInstance->visitListener($this);
} // END - if
// Debug message
- //* DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput(strtoupper($this->getProtocolName()) . '-LISTENER[' . __METHOD__ . ':' . __LINE__ . ']: ' . $visitorInstance->__toString() . ' has visited ' . $this->__toString() . ' - FINISHED');
+ //* DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput(strtoupper($this->getProtocolName()) . '-LISTENER[' . __METHOD__ . ':' . __LINE__ . ']: ' . $visitorInstance->__toString() . ' has visited ' . $this->__toString() . ' - EXIT!');
}
/**
* @return $isset Whether the group is valid
*/
public function isGroupSet ($groupName) {
- //* DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput(__METHOD__.': '.$groupName);
+ //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('[' . __METHOD__ . ':' . __LINE__ . ']: this=' . $this->__toString() . ',groupName=' . $groupName);
return isset($this->listGroups[$groupName]);
}
* @throws ListGroupAlreadyAddedException If the given group is already added
*/
public function addGroup ($groupName) {
- //* DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput(__METHOD__.': '.$groupName . ' - START');
+ //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('[' . __METHOD__ . ':' . __LINE__ . ']: this=' . $this->__toString() . ',groupName=' . $groupName . ' - CALLED!');
// Is the group already added?
if ($this->isGroupSet($groupName)) {
// Throw the exception here
// Add the group which is a simple array
$this->listGroups[$groupName] = ObjectFactory::createObjectByConfiguredName('list_group_class');
- //* DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput(__METHOD__.': '.$groupName . ' - FINISHED');
+ //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('[' . __METHOD__ . ':' . __LINE__ . ']: this=' . $this->__toString() . ',groupName=' . $groupName . ' - EXIT!');
}
/**
* @throws NoListGroupException If the given group is not found
*/
public function addInstance ($groupName, $subGroup, Visitable $visitableInstance) {
- //* DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput(__METHOD__.': '.$groupName . '/' . $subGroup . ' - START');
+ // Debug message
+ //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('[' . __METHOD__ . ':' . __LINE__ . ']: this=' . $this->__toString() . ',groupName=' . $groupName . ',subGroup=' . $subGroup . ',visitableInstance=' . $visitableInstance->__toString() . ' - CALLED!');
+
// Is the group there?
if (!$this->isGroupSet($groupName)) {
// Throw the exception here
// Generate the hash
$hash = $this->generateHash($groupName, $subGroup, $visitableInstance);
+ // Debug message
+ //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('[' . __METHOD__ . ':' . __LINE__ . ']: this=' . $this->__toString() . ',groupName=' . $groupName . ',subGroup=' . $subGroup . ',hash=' . $hash . ' - Calling addEntry() ...');
+
// Now add it to the group list and hash it
- $this->listGroups[$groupName]->addEntry($subGroup, $hash);
+ //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('[' . __METHOD__ . ':' . __LINE__ . ']: this=' . $this->__toString() . ',this->listGroups[' . $groupName . ']=' . $this->listGroups[$groupName]->__toString());
+ //$this->listGroups[$groupName]->addEntry($subGroup, $hash);
// Add the hash to the index
array_push($this->listIndex, $hash);
// Add the instance itself to the list
$this->listEntries[$hash] = $visitableInstance;
- //* DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput(__METHOD__.': '.$groupName . '/' . $subGroup . ' - FINISHED');
+
+ // Debug message
+ //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('[' . __METHOD__ . ':' . __LINE__ . ']: this=' . $this->__toString() . ',groupName=' . $groupName . ',subGroup=' . $subGroup . ' - EXIT!');
}
/**
* @throws NoListGroupException If the given group is not found
*/
public final function getArrayFromList ($list) {
+ // Debug message
+ //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('[' . __METHOD__ . ':' . __LINE__ . ']: this=' . $this->__toString() . ',list[' . gettype($list) . ']=' . $list . ' - CALLED!');
+
// Is the group there?
if ((!is_null($list)) && (!$this->isGroupSet($list))) {
// Throw the exception here
// Walk through all entries
foreach ($this->listIndex as $hash) {
- //* DEBUG: */ print __METHOD__.':hash='.$hash.chr(10);
+ // Debug message
+ //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('[' . __METHOD__ . ':' . __LINE__ . ']: hash=' . $hash);
+
// Is the list entry set?
if ($this->isHashValid($hash)) {
// Add it
array_push($array, $this->listEntries[$hash]);
- //* DEBUG: */ print __METHOD__.": ADDED!\n";
+ //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('[' . __METHOD__ . ':' . __LINE__ . ']: hash=' . $hash . ',array(' . count($array) . ')=' . print_r($array, TRUE) . ' - ADDED!');
} // END - if
} // END - foreach
+ // Debug message
+ //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('[' . __METHOD__ . ':' . __LINE__ . ']: this=' . $this->__toString() . ',list[' . gettype($list) . ']=' . $list . ',array()=' . count($array) . ' - EXIT!');
+
// Return it
return $array;
}
* @throws NoListGroupException If the given group is not found
*/
public function addEntry ($groupName, $entry) {
- //* DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput(__METHOD__.'('.$this->__toString().'): '.$groupName . ' - START');
+ // Debug message
+ //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('[' . __METHOD__ . ':' . __LINE__ . ']: this=' . $this->__toString() . ',groupName=' . $groupName . ' - CALLED!');
+
// Is the group already added?
if (!$this->isGroupSet($groupName)) {
// Throw the exception here
// Generate hash
$hash = $this->generateHash($groupName, $groupName, $entry);
- //* DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('BASE-LIST[' . __METHOD__ . ':' . __LINE__ . ']: groupName=' . $groupName . ', entry=' . $entry . ', hash=' . $hash);
+
+ // Debug message
+ //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('[' . __METHOD__ . ':' . __LINE__ . ']: this=' . $this->__toString() . ',groupName=' . $groupName . ',entry=' . print_r($entry, TRUE) . ', hash=' . $hash);
// Add the hash to the index
array_push($this->listIndex, $hash);
- //* DEBUG: */ print $groupName.'/'.$this->count().chr(10);
+
+ // Debug message
+ //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('[' . __METHOD__ . ':' . __LINE__ . ']: this=' . $this->__toString() . ',groupName=' . $groupName . ',listEntries()=' . count($this->listEntries));
// Now add the entry to the list
$this->listEntries[$hash] = $entry;
- //* DEBUG: */ print $groupName.'/'.count($this->listEntries).chr(10);
- //* DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput(__METHOD__.'('.$this->__toString().'): '.$groupName . ' - FINISHED');
+
+ // Debug message
+ //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('[' . __METHOD__ . ':' . __LINE__ . ']: this=' . $this->__toString() . ',groupName=' . $groupName . ',listEntries()=' . count($this->listEntries) . ' - EXIT!');
}
/**
* @throws NoListGroupException If the given group is not found
*/
public function removeEntry ($groupName, $entry) {
- //* DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput(__METHOD__.'('.$this->__toString().'): '.$groupName . ' - START');
+ // Debug message
+ //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('[' . __METHOD__ . ':' . __LINE__ . ']: this=' . $this->__toString() . ',groupName=' . $groupName . ' - CALLED!');
+
// Is the group already added?
if (!$this->isGroupSet($groupName)) {
// Throw the exception here
// Generate hash
$hash = $this->generateHash($groupName, $groupName, $entry);
- //* DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('BASE-LIST[' . __METHOD__ . ':' . __LINE__ . ']: groupName=' . $groupName . ', entry=' . $entry . ', hash=' . $hash);
+
+ // Debug message
+ //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('[' . __METHOD__ . ':' . __LINE__ . ']: this=' . $this->__toString() . ',groupName=' . $groupName . ',entry=' . $entry . ', hash=' . $hash);
// Remove it from the list ...
unset($this->listEntries[$hash]);
// ... and hash list as well
unset($this->listIndex[array_search($hash, $this->listIndex)]);
- //* DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput(__METHOD__.'('.$this->__toString().'): '.$groupName . ' - FINISHED');
+
+ // Debug message
+ //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('[' . __METHOD__ . ':' . __LINE__ . ']: this=' . $this->__toString() . ',groupName=' . $groupName . ' - EXIT!');
}
/**
* @return $entries The array with all entries
* @throws NoListGroupException If the specified group is invalid
*/
- public function getArrayFromGroup ($groupName) {
+ public function getArrayFromProtocolInstance ($groupName) {
// Is the group valid?
if (!$this->isGroupSet($groupName)) {
// Throw the exception here
}
}
-//
+// [EOF]
?>
*/
public function accept (Visitor $visitorInstance) {
// Debug message
- /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('NETWORK-PACKAGE[' . __METHOD__ . ':' . __LINE__ . ']: ' . $visitorInstance->__toString() . ' has visited - START');
+ /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('NETWORK-PACKAGE[' . __METHOD__ . ':' . __LINE__ . ']: ' . $visitorInstance->__toString() . ' has visited - CALLED!');
// Visit the package
$visitorInstance->visitNetworkPackage($this);
$this->getAssemblerInstance()->accept($visitorInstance);
// Debug message
- /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('NETWORK-PACKAGE[' . __METHOD__ . ':' . __LINE__ . ']: ' . $visitorInstance->__toString() . ' has visited - FINISHED');
+ /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('NETWORK-PACKAGE[' . __METHOD__ . ':' . __LINE__ . ']: ' . $visitorInstance->__toString() . ' has visited - EXIT!');
}
/**
*/
public function accept (Visitor $visitorInstance) {
// Debug message
- //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('POOL[' . __METHOD__ . ':' . __LINE__ . ']: ' . $visitorInstance->__toString() . ' has visited - START');
+ //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('POOL[' . __METHOD__ . ':' . __LINE__ . ']: ' . $visitorInstance->__toString() . ' has visited - CALLED!');
// Visit this pool
$visitorInstance->visitPool($this);
} // END - while
// Debug message
- //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('POOL[' . __METHOD__ . ':' . __LINE__ . ']: ' . $visitorInstance->__toString() . ' has visited - FINISHED');
+ //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('POOL[' . __METHOD__ . ':' . __LINE__ . ']: ' . $visitorInstance->__toString() . ' has visited - EXIT!');
}
/**
*/
public function doShutdown () {
// Debug message
- self::createDebugInstance(__CLASS__)->debugOutput('POOL[' . __METHOD__ . ':' . __LINE__ . ']: Shutting down listener pool - START');
+ /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('POOL[' . __METHOD__ . ':' . __LINE__ . ']: Shutting down listener pool - CALLED!');
// Get a new visitor
$visitorInstance = ObjectFactory::createObjectByConfiguredName('shutdown_listener_pool_visitor_class');
$this->accept($visitorInstance);
// Debug message
- self::createDebugInstance(__CLASS__)->debugOutput('POOL[' . __METHOD__ . ':' . __LINE__ . ']: Shutting down listener pool - FINISHED');
+ /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('POOL[' . __METHOD__ . ':' . __LINE__ . ']: Shutting down listener pool - EXIT!');
}
}
// Default is no socket
$socketResource = FALSE;
- // Temporary resolve recipient field
- die(__METHOD__ . ': UNFINISHED!' . PHP_EOL);
- $unlData = explode(':', HubTools::resolveSessionId($packageData[NetworkPackage::PACKAGE_DATA_RECIPIENT]));
+ // Resolve recipient (UNL) into a handler instance
+ $handlerInstance = ProtocolHandlerFactory::createProtocolHandlerFromPackageData($packageData);
+
+ // Get UNL data
+ $unlData = $handlerInstance->getUniversalNodeLocatorData();
// Make sure it is a valid Universal Node Locator array (3 elements)
- assert(count($unlData) == 3);
+ assert(isset($unlData[UniversalNodeLocator::UNL_PART_PROTOCOL]));
+ assert(isset($unlData[UniversalNodeLocator::UNL_PART_ADDRESS]));
+ assert(isset($unlData[UniversalNodeLocator::UNL_PART_PORT]));
// Debug message
- //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('POOL[' . __METHOD__ . ':' . __LINE__ . ']: Checking ' . count($this->getAllSockets()) . ' socket(s),unlData[0]=' . $unlData[0] . ',unlData[1]=' . $unlData[1] . ' ...');
+ //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('POOL[' . __METHOD__ . ':' . __LINE__ . ']: Checking ' . count($this->getAllSockets()) . ' socket(s),unlData[' . UniversalNodeLocator::UNL_PART_ADDRESS . ']=' . $unlData[UniversalNodeLocator::UNL_PART_ADDRESS] . ',unlData[' . UniversalNodeLocator::UNL_PART_PORT . ']=' . $unlData[UniversalNodeLocator::UNL_PART_PORT] . ' ...');
// Default is all sockets
$sockets = $this->getAllSockets();
// Get
// If the "peer" IP and recipient is same, use it
- if ($peerIp == $unlData[0]) {
+ if ($peerIp == $unlData[UniversalNodeLocator::UNL_PART_ADDRESS]) {
// IPs match, so take the socket and quit this loop
$socketResource = $socketArray[self::SOCKET_ARRAY_RESOURCE];
*/
private function getRegistryKeyFromListener (Listenable $listenerInstance) {
// Debug message
- //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('SOCKET-REGISTRY[' . __METHOD__ . ':' . __LINE__ . ']: listenerInstance=' . $listenerInstance->__toString() . ' - ENTERED!');
+ //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('SOCKET-REGISTRY[' . __METHOD__ . ':' . __LINE__ . ']: this=' . $this->__toString() . ',listenerInstance=' . $listenerInstance->__toString() . ' - ENTERED!');
// Get the key
$key = $listenerInstance->getConnectionType();
$key = $this->getRegistryKeyFromListener($listenerInstance);
// Debug message
- //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('SOCKET-REGISTRY[' . __METHOD__ . ':' . __LINE__ . ']: listener=' . $listenerInstance->getConnectionType() . ',socketResource[' . gettype($socketResource) . ']=' . $socketResource . ',key=' . $key . ' - Trying to get instance ...');
+ //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('SOCKET-REGISTRY[' . __METHOD__ . ':' . __LINE__ . ']: this=' . $this->__toString() . ',listener=' . $listenerInstance->getConnectionType() . ',socketResource[' . gettype($socketResource) . ']=' . $socketResource . ',key=' . $key . ' - Trying to get instance ...');
// Get the registry
$registryInstance = $this->getInstance($key);
$socketKey = $this->getSubRegistryKey($listenerInstance);
// Debug message
- //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('SOCKET-REGISTRY[' . __METHOD__ . ':' . __LINE__ . ']: listener=' . $listenerInstance->getConnectionType() . ',socketResource[' . gettype($socketResource) . ']=' . $socketResource . ',key=' . $key . ',socketKey=' . $socketKey . ' - Checking existence ...');
+ //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('SOCKET-REGISTRY[' . __METHOD__ . ':' . __LINE__ . ']: this=' . $this->__toString() . ',listener=' . $listenerInstance->getConnectionType() . ',socketResource[' . gettype($socketResource) . ']=' . $socketResource . ',key=' . $key . ',socketKey=' . $socketKey . ' - Checking existence ...');
// Is it there?
if ($registryInstance->instanceExists($socketKey)) {
*/
private function initObjectRegistry () {
// Output debug message
- self::createDebugInstance(__CLASS__)->debugOutput('TAGS[' . __METHOD__ . ':' . __LINE__ . ']: Initializing object registry - START');
+ /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('TAGS[' . __METHOD__ . ':' . __LINE__ . ']: Initializing object registry - CALLED!');
// Get the application instance
$applicationInstance = Registry::getRegistry()->getInstance('app');
$this->getTemplateInstance()->renderXmlContent();
// Output debug message
- self::createDebugInstance(__CLASS__)->debugOutput('TAGS[' . __METHOD__ . ':' . __LINE__ . ']: Initializing object registry - FINISHED');
+ /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('TAGS[' . __METHOD__ . ':' . __LINE__ . ']: Initializing object registry - EXIT!');
}
/**
*/
protected function resolveUniversalNodeLocatorBySessionId ($sessionId) {
// Init variable
- die(__METHOD__ . ': UNFINISHED: sessionId=' . $sessionId . PHP_EOL);
$recipientUniversalNodeLocator = 'invalid://invalid:invalid';
// And ask it for Universal Node Locator by given session id
$recipient = $this->getDhtInstance()->findNodeLocalBySessionId($sessionId);
+ //* DEBUG-DIE: */ die(__METHOD__ . ': UNFINISHED: recipient[' . gettype($recipient) . ']=' . print_r($recipient, TRUE) . ',sessionId=' . $sessionId . PHP_EOL);
// Is the recipient valid?
if (isset($recipient[NodeDistributedHashTableDatabaseWrapper::DB_COLUMN_EXTERNAL_ADDRESS])) {
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
class UniversalNodeLocator extends BaseFrameworkSystem implements LocateableNode {
+ //------- UNL parts -------
+ // Protocol
+ const UNL_PART_PROTOCOL = 'protocol';
+ // Address
+ const UNL_PART_ADDRESS = 'address';
+ // Extra part
+ const UNL_PART_EXTRA = 'extra';
+ // Port (if any)
+ const UNL_PART_PORT = 'port';
+
/**
* UNL data array
*/
*/
public function visitPool (Poolable $poolInstance) {
// A pool doesn't normally have any raw data waiting
+ //* DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('[' . __METHOD__ . ':' . __LINE__ . ' ]: poolInstance=' . $poolInstance->__toString() . ' - CALLED!');
}
/**
* traffic. This is why we don't call its monitorIncomingRawData()
* method.
*/
+ //* DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('[' . __METHOD__ . ':' . __LINE__ . ' ]: listenerInstance=' . $listenerInstance->__toString() . ' - CALLED!');
}
/**
*/
public function visitDecorator (BaseDecorator $decoratorInstance) {
// Do monitor here
- //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('VISITOR: Visiting ' . $listenerInstance->__toString() . ' - START');
+ //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('[' . __METHOD__ . ':' . __LINE__ . ' ]: Visiting ' . $listenerInstance->__toString() . ' - CALLED!');
$decoratorInstance->monitorIncomingRawData($this->getReceiverInstance());
- //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('VISITOR: Visiting ' . $listenerInstance->__toString() . ' - FINISH');
+ //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('[' . __METHOD__ . ':' . __LINE__ . ' ]: Visiting ' . $listenerInstance->__toString() . ' - FINISH');
}
}
/**
* Creates an instance of this class
*
- * @return $visitorInstance An instance a Visitorable class
+ * @return $visitorInstance An instance a Visitorable class
*/
public static final function createShutdownListenerPoolVisitor () {
// Get new instance
*/
public function visitPool (Poolable $poolInstance) {
// Debug message
- self::createDebugInstance(__CLASS__)->debugOutput('VISITOR: Visit of ' . $poolInstance->__toString() . ' - START');
+ /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('[' . __METHOD__ . ':' . __LINE__ . ' ]: Visit of ' . $poolInstance->__toString() . ' - CALLED!');
// Pre-shutdown the pool
$poolInstance->preShutdown();
// Debug message
- self::createDebugInstance(__CLASS__)->debugOutput('VISITOR: Visit of ' . $poolInstance->__toString() . ' - FINISHED');
+ /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('[' . __METHOD__ . ':' . __LINE__ . ' ]: Visit of ' . $poolInstance->__toString() . ' - EXIT!');
}
/**
*/
public function visitDecorator (Listenable $decoratorInstance) {
// Debug message
- self::createDebugInstance(__CLASS__)->debugOutput('VISITOR: Visit of ' . $decoratorInstance->__toString() . ' - START');
+ /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('[' . __METHOD__ . ':' . __LINE__ . ' ]: Visit of ' . $decoratorInstance->__toString() . ' - CALLED!');
// Pre-shutdown the pool
$decoratorInstance->doShutdown();
// Debug message
- self::createDebugInstance(__CLASS__)->debugOutput('VISITOR: Visit of ' . $decoratorInstance->__toString() . ' - FINISHED');
+ /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('[' . __METHOD__ . ':' . __LINE__ . ' ]: Visit of ' . $decoratorInstance->__toString() . ' - EXIT!');
}
/**
*/
public function visitListener (Listenable $listenerInstance) {
// Debug message
- self::createDebugInstance(__CLASS__)->debugOutput('VISITOR: Visit of ' . $listenerInstance->__toString() . ' - START');
+ /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('[' . __METHOD__ . ':' . __LINE__ . ' ]: Visit of ' . $listenerInstance->__toString() . ' - CALLED!');
// Pre-shutdown the pool
$listenerInstance->doShutdown();
// Debug message
- self::createDebugInstance(__CLASS__)->debugOutput('VISITOR: Visit of ' . $listenerInstance->__toString() . ' - FINISHED');
+ /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('[' . __METHOD__ . ':' . __LINE__ . ' ]: Visit of ' . $listenerInstance->__toString() . ' - EXIT!');
}
}
*/
public function visitTask (Taskable $taskInstance) {
// Execute the task from this visitor
- //* DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('VISITOR: Visiting task ' . $taskInstance->__toString() . ' - START');
+ //* DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('[' . __METHOD__ . ':' . __LINE__ . ' ]: Visiting task ' . $taskInstance->__toString() . ' - CALLED!');
$taskInstance->executeTask();
- //* DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('VISITOR: Visiting task ' . $taskInstance->__toString() . ' - FINISHED');
+ //* DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('[' . __METHOD__ . ':' . __LINE__ . ' ]: Visiting task ' . $taskInstance->__toString() . ' - EXIT!');
}
/**
*/
public function visitListener (Listenable $listenerInstance) {
// Do "listen" here
- //* DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('VISITOR: Visiting ' . $listenerInstance->__toString() . ' - START');
+ //* DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('[' . __METHOD__ . ':' . __LINE__ . ' ]: Visiting ' . $listenerInstance->__toString() . ' - CALLED!');
$listenerInstance->doListen();
- //* DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('VISITOR: Visiting ' . $listenerInstance->__toString() . ' - FINISH');
+ //* DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('[' . __METHOD__ . ':' . __LINE__ . ' ]: Visiting ' . $listenerInstance->__toString() . ' - FINISH');
}
/**
-Subproject commit bb3c846b710e4aa1e8706ca115c1e1ce130e1a2f
+Subproject commit e20363d6973c8b2cb0aa25a869501d7c7a6ac755