*
* @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.');
* @return void
*/
public function discoverRecipients (array $packageData) {
- // Get recipients list instance
- $listInstance = RecipientListFactory::createRecipientListInstance();
-
// 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:
+ case NetworkPackage::NETWORK_TARGET_UPPER_NODES:
// Get all bootstrap nodes
- foreach (explode(BaseHubSystem::BOOTSTRAP_NODES_SEPERATOR, $this->getConfigInstance()->getConfigEntry('hub_bootstrap_nodes')) as $node) {
+ foreach (explode(BaseHubSystem::BOOTSTRAP_NODES_SEPARATOR, $this->getConfigInstance()->getConfigEntry('hub_bootstrap_nodes')) as $ipPort) {
+ // Is maximum reached?
+ if ($this->getListInstance()->count() == $this->getConfigInstance()->getConfigEntry('package_recipient_max_count')) {
+ // Debug message
+ /* DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('DISCOVERY: Going to abort at maximum of ' . $this->getConfigInstance()->getConfigEntry('package_recipient_max_count') . ' recipients!');
+
+ // Then stop adding more
+ break;
+ } // END - if
+
+ // Debug message
+ /* DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('DISCOVERY: Adding node ' . $ipPort . ' as recipient.');
+
// Add the entry
- $listInstance->addEntry('ip_port', $node);
+ $this->getListInstance()->addEntry('ip_port', $ipPort);
} // 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();
- }
+ // Determine own port
+ $port = $this->getConfigInstance()->getConfigEntry('node_listen_port');
- // Get port and add it
- $ipPort = $ip . ':' . $this->getConfigInstance()->getConfigEntry('node_' . $this->determineProtocolByPackageData($packageData) . '_listen_port');
+ // Determine IP or 'external_ip' if set
+ $ip = HubTools::determineOwnExternalIp();
- // Add it to the list
- $listInstance->addEntry('ip_port', $ipPort);
+ // Is it not empty?
+ if (!empty($ip)) {
+ // Add it to the list
+ $this->getListInstance()->addEntry('ip_port', $ip . ':' . $port);
+ } // END - if
break;
- // This may be a direct recipient (hub's session id)
+ // This may be a direct recipient (node's session id)
default:
- $this->partialStub('Please add code handling recipients ' . $packageData[NetworkPackage::PACKAGE_DATA_RECIPIENT]);
+ /*
+ * Try to solve it, if an exception comes back, it is not a
+ * session-id, nor IP:port and not a hostname:port combination.
+ */
+ try {
+ // "Explode" all recipients
+ $recipients = explode(NetworkPackage::PACKAGE_RECIPIENT_SEPARATOR, $packageData[NetworkPackage::PACKAGE_DATA_RECIPIENT]);
+
+ // Is maximum reached?
+ assert(count($recipients) <= $this->getConfigInstance()->getConfigEntry('package_recipient_max_count'));
+
+ // Try it on all
+ foreach ($recipients as $recipient) {
+ // Try to sole a single recipient
+ $ipPort = HubTools::resolveSessionId($recipient, $packageData[NetworkPackage::PACKAGE_DATA_PROTOCOL]);
+
+ // Add it as recipient
+ $this->getListInstance()->addEntry('ip_port', $ipPort);
+ } // END - foreach
+ } catch (FrameworkException $e) {
+ // Didn't work, pleace add more code
+ $this->partialStub('Please add code handling recipients ' . $packageData[NetworkPackage::PACKAGE_DATA_RECIPIENT] . ',packageData=' . print_r($packageData, true) . ',exception=' . $e->__toString() . ',message=' . $e->getMessage());
+ }
break;
} // END - switch
}
+ /**
+ * 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) {
+ // 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: 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: Recipient ' . $recipient[0] . ' is different than own external ip (' . HubTools::determineOwnExternalIp() . ') nor internal ip (' . $this->getConfigInstance()->getServerAddress() . '), need to forward (not yet implemented)!');
+
+ // This package is to be delivered to someone else, so add it
+ $this->getListInstance()->addEntry('ip_port', $decodedData[NetworkPackage::PACKAGE_DATA_RECIPIENT]);
+ }
+ }
+
/**
* "Getter" for recipient iterator
*
* @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]