/**
* A general hub node class
*
- * @author Roland Haeder <webmaster@ship-simu.org>
+ * @author Roland Haeder <webmaster@shipsimu.org>
* @version 0.0.0
* @copyright Copyright (c) 2007, 2008 Roland Haeder, 2009 - 2012 Hub Developer Team
* @license GNU GPL 3.0 or any newer version
- * @link http://www.ship-simu.org
+ * @link http://www.shipsimu.org
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
const OBJECT_LIST_SEPARATOR = ',';
/**
- * IP/port number of bootstrapping node
+ * IP/port number of bootstrap node
*/
private $bootIpPort = '';
private $queueConnectorInstance = NULL;
/**
- * Whether this node is anncounced (KEEP ON false!)
+ * Whether this node is anncounced (keep on FALSE!)
* @deprecated
*/
- private $hubIsAnnounced = false;
+ private $hubIsAnnounced = FALSE;
/**
- * Whether this hub is active (default: false)
+ * Whether this hub is active (default: FALSE)
*/
- private $isActive = false;
+ private $isActive = FALSE;
/**
- * Whether this node accepts announcements (default: false)
+ * Whether this node accepts announcements (default: FALSE)
*/
- private $acceptAnnouncements = false;
+ private $acceptAnnouncements = FALSE;
+
+ /**
+ * Whether this node accepts DHT bootstrap requests (default: FALSE)
+ */
+ private $acceptDhtBootstrap = FALSE;
/**
* Protected constructor
* @return void
*/
private function generatePrivateKeyAndHash (LocalSearchCriteria $searchInstance) {
+ // Get an RNG instance
+ $rngInstance = ObjectFactory::createObjectByConfiguredName('rng_class');
+
// Generate a pseudo-random string
- $randomString = $this->generateRandomString(255);
+ $randomString = $rngInstance->randomString(255);
// Hash and encrypt the string so we become a node id (also documented as "hub id")
$this->setPrivateKey($this->getCryptoInstance()->encryptString($randomString));
}
/**
- * Checks whether the given IP address matches one of the bootstrapping nodes
+ * Checks whether the given IP address matches one of the bootstrap nodes
*
* @param $remoteAddr IP address to checkout against our bootstrapping list
* @return $isFound Whether the IP is found
*/
- protected function ifAddressMatchesBootstrappingNodes ($remoteAddr) {
+ protected function ifAddressMatchesBootstrapNodes ($remoteAddr) {
// By default nothing is found
- $isFound = false;
+ $isFound = FALSE;
// Run through all configured IPs
foreach (explode(BaseHubSystem::BOOTSTRAP_NODES_SEPARATOR, $this->getConfigInstance()->getConfigEntry('hub_bootstrap_nodes')) as $ipPort) {
// Does it match?
if ($ipPortArray[0] == $remoteAddr) {
// Found it!
- $isFound = true;
+ $isFound = TRUE;
// Remember the port number
$this->bootIpPort = $ipPort;
// Output message
- self::createDebugInstance(__CLASS__)->debugOutput('BOOTSTRAP: ' . __FUNCTION__ . '[' . __LINE__ . ']: IP matches remote address ' . $ipPort . '.');
+ self::createDebugInstance(__CLASS__)->debugOutput('BOOTSTRAP: ' . __FUNCTION__ . '[' . __METHOD__ . ':' . __LINE__ . ']: IP matches remote address ' . $ipPort . '.');
// Stop further searching
break;
* IP matches listen address. At this point we really don't care
* if we can really listen on that address
*/
- $isFound = true;
+ $isFound = TRUE;
// Remember the port number
$this->bootIpPort = $ipPort;
// Output message
- self::createDebugInstance(__CLASS__)->debugOutput('BOOTSTRAP: ' . __FUNCTION__ . '[' . __LINE__ . ']: IP matches listen address ' . $ipPort . '.');
+ self::createDebugInstance(__CLASS__)->debugOutput('BOOTSTRAP: ' . __FUNCTION__ . '[' . __METHOD__ . ':' . __LINE__ . ']: IP matches listen address ' . $ipPort . '.');
// Stop further searching
break;
// Output message
self::createDebugInstance(__CLASS__)->debugOutput('BOOTSTRAP: Re-using found node-id: ' . $this->getNodeId() . '');
} else {
+ // Get an RNG instance
+ $rngInstance = ObjectFactory::createObjectByConfiguredName('rng_class');
+
// Generate a pseudo-random string
- $randomString = $this->generateRandomString(255);
+ $randomString = $rngInstance->randomString(255);
// Hash and encrypt the string so we become a node id (also documented as "hub id")
$this->setNodeId($this->getCryptoInstance()->hashString($this->getCryptoInstance()->encryptString($randomString)));
$searchInstance = ObjectFactory::createObjectByConfiguredName('search_criteria_class');
// Search for the node number one which is hard-coded the default
- $searchInstance->addCriteria(NodeInformationDatabaseWrapper::DB_COLUMN_NODE_NR, 1);
- $searchInstance->addCriteria(NodeInformationDatabaseWrapper::DB_COLUMN_NODE_TYPE, $this->getRequestInstance()->getRequestElement('mode'));
+ $searchInstance->addCriteria(NodeInformationDatabaseWrapper::DB_COLUMN_NODE_NR , 1);
+ $searchInstance->addCriteria(NodeInformationDatabaseWrapper::DB_COLUMN_NODE_MODE, $this->getRequestInstance()->getRequestElement('mode'));
+ $searchInstance->addCriteria(NodeInformationDatabaseWrapper::DB_COLUMN_NODE_ID , $this->getNodeId());
$searchInstance->setLimit(1);
+ // Remember it for later usage
+ $this->setSearchInstance($searchInstance);
+
// Get a random string
$randomString = $this->generateRamdomString(255);
* "tables". This allows a smooth update for the underlaying
* database table.
*/
- $this->generatePrivateKeyAndHash($searchInstance);
+ $this->generatePrivateKeyAndHash($this->getSearchInstance());
} else {
// Get the node id from result and set it
$this->setPrivateKey(base64_decode($this->getField(NodeInformationDatabaseWrapper::DB_COLUMN_PRIVATE_KEY)));
* Generate it in a private method (no confusion with 'private
* method access' and 'private key' here! ;-)).
*/
- $this->generatePrivateKeyAndHash($searchInstance);
+ $this->generatePrivateKeyAndHash($this->getSearchInstance());
}
}
assert($requestInstance instanceof Requestable);
// Add node number and type
- $criteriaInstance->addCriteria(NodeInformationDatabaseWrapper::DB_COLUMN_NODE_NR, 1);
- $criteriaInstance->addCriteria(NodeInformationDatabaseWrapper::DB_COLUMN_NODE_TYPE, $requestInstance->getRequestElement('mode'));
+ $criteriaInstance->addCriteria(NodeInformationDatabaseWrapper::DB_COLUMN_NODE_NR , 1);
+ $criteriaInstance->addCriteria(NodeInformationDatabaseWrapper::DB_COLUMN_NODE_MODE, $requestInstance->getRequestElement('mode'));
// Add the node id
$criteriaInstance->addCriteria(NodeInformationDatabaseWrapper::DB_COLUMN_NODE_ID, $this->getNodeId());
*/
public function announceToUpperNodes (Taskable $taskInstance) {
// Is this hub node announced?
- if ($this->hubIsAnnounced === true) {
+ if ($this->hubIsAnnounced === TRUE) {
// Already announced!
throw new NodeAlreadyAnnouncedException($this, self::EXCEPTION_HUB_ALREADY_ANNOUNCED);
} // END - if
$helperInstance->sendPackage($this);
// Change the state, this should be the last line except debug output
- $this->getStateInstance()->nodeAnnouncedToUpperHubs();
+ $this->getStateInstance()->nodeAnnouncingToUpperHubs();
// Debug output
self::createDebugInstance(__CLASS__)->debugOutput('HUB-Announcement: FINISHED');
*/
public function doSelfConnection (Taskable $taskInstance) {
// Debug output
- self::createDebugInstance(__CLASS__)->debugOutput('HUB: Self Connection: START (taskInstance=' . $taskInstance->__toString(). ')');
+ self::createDebugInstance(__CLASS__)->debugOutput('NODE[' . __METHOD__ . ':' . __LINE__ . ']: Self Connection: START (taskInstance=' . $taskInstance->__toString(). ')');
// Get a helper instance
$helperInstance = ObjectFactory::createObjectByConfiguredName('node_self_connect_helper_class', array($this));
$helperInstance->sendPackage($this);
// Debug output
- self::createDebugInstance(__CLASS__)->debugOutput('HUB: Self Connection: FINISHED');
+ self::createDebugInstance(__CLASS__)->debugOutput('NODE[' . __METHOD__ . ':' . __LINE__ . ']: Self Connection: FINISHED');
}
/**
* Activates the hub by doing some final preparation and setting
- * $hubIsActive to true
+ * $hubIsActive to TRUE.
*
* @param $requestInstance A Requestable class
* @param $responseInstance A Responseable class
*/
public function initializeListenerPool () {
// Debug output
- self::createDebugInstance(__CLASS__)->debugOutput('HUB: Initialize listener: START');
+ self::createDebugInstance(__CLASS__)->debugOutput('NODE[' . __METHOD__ . ':' . __LINE__ . ']: Initialize listener: START');
// Get a new pool instance
$this->setListenerPoolInstance(ObjectFactory::createObjectByConfiguredName('listener_pool_class', array($this)));
$this->getListenerPoolInstance()->addListener($decoratorInstance);
// Debug output
- self::createDebugInstance(__CLASS__)->debugOutput('HUB: Initialize listener: FINISHED.');
+ self::createDebugInstance(__CLASS__)->debugOutput('NODE[' . __METHOD__ . ':' . __LINE__ . ']: Initialize listener: FINISHED.');
}
/**
* @param $isActive Whether the hub is active
* @return void
*/
- public final function enableIsActive ($isActive = true) {
+ public final function enableIsActive ($isActive = TRUE) {
$this->isActive = (bool) $isActive;
}
*/
public final function isAcceptingAnnouncements () {
// Check it (this node must be active and not shutdown!)
- $acceptAnnouncements = (($this->acceptAnnouncements === true) && ($this->isNodeActive()));
+ $acceptAnnouncements = (($this->acceptAnnouncements === TRUE) && ($this->isNodeActive()));
// Return it
return $acceptAnnouncements;
}
+ /**
+ * Checks whether this node accepts DHT bootstrap requests
+ *
+ * @return $acceptDhtBootstrap Whether this node accepts DHT bootstrap requests
+ */
+ public final function isAcceptingDhtBootstrap () {
+ // Check it (this node must be active and not shutdown!)
+ $acceptDhtBootstrap = (($this->acceptDhtBootstrap === TRUE) && ($this->isNodeActive()));
+
+ // Return it
+ return $acceptDhtBootstrap;
+ }
+
/**
* Checks whether this node has attempted to announce itself
*
*/
public function ifNodeHasAnnounced () {
// Debug message
- /* DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('NODE: ifNodeHasAnnounced(): state=' . $this->getStateInstance()->getStateName());
+ //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('NODE[' . __METHOD__ . ':' . __LINE__ . ']: ifNodeHasAnnounced(): state=' . $this->getStateInstance()->getStateName());
// Simply check the state of this node
$hasAnnounced = ($this->getStateInstance() instanceof NodeAnnouncedState);
// Debug message
- /* DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('NODE: ifNodeHasAnnounced(): hasAnnounced=' . intval($hasAnnounced));
+ //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('NODE[' . __METHOD__ . ':' . __LINE__ . ']: ifNodeHasAnnounced(): hasAnnounced=' . intval($hasAnnounced));
// Return it
return $hasAnnounced;
*/
public function ifNodeHasAnnouncementCompleted () {
// Debug message
- /* DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('NODE: ifNodeHasAnnouncementCompleted(): state=' . $this->getStateInstance()->getStateName());
+ //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('NODE[' . __METHOD__ . ':' . __LINE__ . ']: ifNodeHasAnnouncementCompleted(): state=' . $this->getStateInstance()->getStateName());
// Simply check the state of this node
$hasAnnouncementCompleted = ($this->getStateInstance() instanceof NodeAnnouncementCompletedState);
// Debug message
- /* DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('NODE: ifNodeHasAnnouncementCompleted(): hasAnnouncementCompleted=' . intval($hasAnnouncementCompleted));
+ //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('NODE[' . __METHOD__ . ':' . __LINE__ . ']: ifNodeHasAnnouncementCompleted(): hasAnnouncementCompleted=' . intval($hasAnnouncementCompleted));
// Return it
return $hasAnnouncementCompleted;
/**
* Enables whether this node accepts announcements
*
- * @param $acceptAnnouncements Whether this node accepts announcements (default: true)
+ * @param $acceptAnnouncements Whether this node accepts announcements (default: TRUE)
* @return void
*/
- protected final function enableAcceptingAnnouncements ($acceptAnnouncements = true) {
+ protected final function enableAcceptingAnnouncements ($acceptAnnouncements = TRUE) {
$this->acceptAnnouncements = $acceptAnnouncements;
}
+ /**
+ * Enables whether this node accepts DHT bootstrap requests
+ *
+ * @param $acceptDhtBootstrap Whether this node accepts DHT bootstrap requests (default: TRUE)
+ * @return void
+ */
+ public final function enableAcceptDhtBootstrap ($acceptDhtBootstrap = TRUE) {
+ /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('NODE[' . __METHOD__ . ':' . __LINE__ . ']: Enabling DHT bootstrap requests ...');
+ $this->acceptDhtBootstrap = $acceptDhtBootstrap;
+ }
+
/**
* Checks wether this node is accepting node-list requests
*
/*
* Only 'regular' nodes does not accept such requests, checking
* HubRegularNode is faster, but if e.g. HubRegularI2PNode will be
- * added then the next check will be true.
+ * added then the next check will be TRUE.
*/
$acceptsRequest = ((!$this instanceof HubRegularNode) && ($this->getRequestInstance()->getRequestElement('mode') != self::NODE_TYPE_REGULAR));
*/
public final function getAddressPortArray () {
// Get IP and port
- $addressPortArray = explode(':', $this->getAddressPort();
+ $addressPortArray = explode(':', $this->getAddressPort());
// Return it
return $addressPortArray;
// ... and return it
return $objectList;
}
+
+ /**
+ * Adds all required elements from given array into data set instance
+ *
+ * @param $dataSetInstance An instance of a StoreableCriteria class
+ * @param $nodeData An array with valid node data
+ * @return void
+ */
+ public function addArrayToDataSet (StoreableCriteria $dataSetInstance, array $nodeData) {
+ // Add all data the array provides
+ foreach (NodeDistributedHashTableDatabaseWrapper::getAllElements() as $element) {
+ // Is the element there?
+ if (isset($nodeData[$element])) {
+ // Add it
+ $dataSetInstance->addCriteria($element, $nodeData[$element]);
+ } else {
+ // Output warning message
+ /* DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('NODE[' . __METHOD__ . ':' . __LINE__ . ']: addArrayToDataSet(): Element ' . $element . ' not found in nodeData array.');
+ }
+ } // END - foreac
+ }
}
// [EOF]