*
* @author Roland Haeder <webmaster@ship-simu.org>
* @version 0.0.0
- * @copyright Copyright (c) 2007, 2008 Roland Haeder, 2009 - 2011 Core Developer Team
+ * @copyright Copyright (c) 2007, 2008 Roland Haeder, 2009 - 2012 Core Developer Team
* @license GNU GPL 3.0 or any newer version
* @link http://www.ship-simu.org
*
// Get an instance of this class
$discoveryInstance = new PackageRecipientDiscovery();
+ // Get recipients list instance and set it
+ $listInstance = RecipientListFactory::createRecipientListInstance();
+ $discoveryInstance->setListInstance($listInstance);
+
// Output debug message
- $discoveryInstance->debugOutput('RECIPIENT-DISCOVERY: Initialized.');
+ self::createDebugInstance(__CLASS__)->debugOutput('RECIPIENT-DISCOVERY[' . __LINE__ . ']: Initialized.');
// Return the prepared instance
return $discoveryInstance;
* @return void
*/
public function discoverRecipients (array $packageData) {
- // Get recipients list instance
- $listInstance = RecipientListFactory::createRecipientListInstance();
+ // This must be available
+ //* DEBUG: */ print $this->__toString() . ': packageData=' . print_r($packageData, TRUE);
+ assert(isset($packageData[NetworkPackage::PACKAGE_DATA_RECIPIENT]));
+
+ // First try out the direct recipient (session id)
+ try {
+ // Get instance (should not break)
+ $recipientInstance = ObjectFactory::createObjectByConfiguredName('direct_recipient_class');
+
+ // Try to solve it
+ $recipientInstance->resolveRecipient($packageData[NetworkPackage::PACKAGE_DATA_RECIPIENT], $this->getListInstance());
+ } catch (FrameworkException $e) {
+ // Didn't work, so try the non-generic, depending recipient field itself (this may fail)
+ try {
+ // Try to find the right class
+ $recipientInstance = ObjectFactory::createObjectByConfiguredName(strtolower($packageData[NetworkPackage::PACKAGE_DATA_RECIPIENT]) . '_recipient_class');
+
+ // And try to solve again
+ $recipientInstance->resolveRecipient($packageData[NetworkPackage::PACKAGE_DATA_RECIPIENT], $this->getListInstance());
+ } catch (FrameworkException $e) {
+ // Could not find class, what ever failed
+ $this->debugInstance($e->getMessage());
+ }
+ }
+ }
+
+ /**
+ * Tries to discover all recipients by given decoded package data.
+ *
+ * @param $decodedData Raw raw package data array
+ * @return void
+ * @todo Add some validation of recipient field, e.g. ip:port is found
+ * @todo The if() does only check for TCP, not UDP, e.g. try to get a $handlerInstance here
+ */
+ public function discoverRawRecipients (array $decodedData) {
+ // This must be available
+ assert(isset($decodedData[NetworkPackage::PACKAGE_DATA_RECIPIENT]));
+
+ // First clear all recipients
+ $this->clearRecipients();
+
+ // Explode 'recipient', first element is the IP/hostname
+ $recipient = explode(':', $decodedData[NetworkPackage::PACKAGE_DATA_RECIPIENT]);
+
+ // Is the 'recipient' field same as this peer's IP?
+ if ((($recipient[0] == HubTools::determineOwnExternalIp()) && ($recipient[1] == $this->getConfigInstance()->getConfigEntry('node_listen_port'))) || ($recipient[0] == $this->getConfigInstance()->getServerAddress())) {
+ /*
+ * Is same as own external IP + TCP/UDP listen port or internal IP, don't do anything here so other
+ * classes found an empty recipient list for internal (own) handling
+ * of the original content.
+ */
+
+ // Debug output (may flood)
+ /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('RECIPIENT-DISCOVERY[' . __LINE__ . ']: Recipient ' . $recipient[0] . ' matches own ip (' . HubTools::determineOwnExternalIp() . ' or ' . $this->getConfigInstance()->getServerAddress() . ')');
+ } else {
+ // Debug output (may flood)
+ /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('RECIPIENT-DISCOVERY[' . __LINE__ . ']: Recipient ' . $recipient[0] . ' is different than own external ip (' . HubTools::determineOwnExternalIp() . ') nor internal ip (' . $this->getConfigInstance()->getServerAddress() . '), need to forward (not yet implemented)!');
- // We do some rudimentary checks but this might be a bit ugly
- switch ($packageData[NetworkPackage::PACKAGE_DATA_RECIPIENT]) {
- // All upper hubs, these are currently the bootstrap nodes and later on prepended list-nodes
- case NetworkPackage::NETWORK_TARGET_UPPER_HUBS:
- // Get all bootstrap nodes
- foreach (explode(';', $this->getConfigInstance()->getConfigEntry('hub_bootstrap_nodes')) as $node) {
- // Add the entry
- $listInstance->addEntry('ip_port', $node);
- } // END - foreach
- break;
-
- // The target 'self' is always the external IP address!
- case NetworkPackage::NETWORK_TARGET_SELF:
- // Is the external_ip config entry set?
- if ($this->getConfigInstance()->getConfigEntry('external_ip') != '') {
- // Use it as external ip
- $ip = $this->getConfigInstance()->getConfigEntry('external_ip');
- } else {
- // Determine own external ip by connecting to my (coder) server at 188.138.90.169
- $ip = ConsoleTools::determineExternalIp();
- }
-
- // Get mode
- $mode = Registry::getRegistry()->getInstance('app')->getRequestInstance()->getRequestElement('mode');
-
- // Set prefix
- $prefix = '';
- if ($mode != 'regular') {
- // Is a special node
- $prefix = $mode . '_';
- } // END - if
-
- // Get port and add it
- $ipPort = $ip . ':' . $this->getConfigInstance()->getConfigEntry($prefix . 'node_' . $this->determineProtocolByPackageData($packageData) . '_listen_port');
-
- // Add it to the list
- $listInstance->addEntry('ip_port', $ipPort);
- break;
-
- // This may be a direct recipient (hub's session id)
- default:
- $this->partialStub('Please add code handling recipients ' . $packageData[NetworkPackage::PACKAGE_DATA_RECIPIENT]);
- break;
- } // END - switch
+ // This package is to be delivered to someone else, so add it
+ $this->getListInstance()->addEntry('ip_port', $decodedData[NetworkPackage::PACKAGE_DATA_RECIPIENT]);
+ }
}
/**
* @return $iteratorInstance An instance of a Iterateable object
*/
public function getIterator () {
- // Get list instance
- $listInstance = RecipientListFactory::createRecipientListInstance();
-
// Get iterator from it
- $iteratorInstance = $listInstance->getIterator();
+ $iteratorInstance = $this->getListInstance()->getIterator();
// Return it
return $iteratorInstance;
}
+
+ /**
+ * Checks whether the recipient list is empty
+ *
+ * @return $isEmpty Whether the recipient list is empty
+ */
+ public function isRecipientListEmpty () {
+ // Check it ...
+ $isEmpty = ($this->getListInstance()->count() == 0);
+
+ // Return it
+ return $isEmpty;
+ }
+
+ /**
+ * Clears all recipients for e.g. another package to deliver. This method
+ * simply clears the inner list instance.
+ *
+ * @return void
+ */
+ public function clearRecipients () {
+ // Clear the list
+ $this->getListInstance()->clearList();
+ }
}
// [EOF]