- New InvalidSessionIdException added which will be thrown if the session id doesn't pass a preg_match() test
- TODO: That above mentioned preg_match() and the other now needs to be moved out
- New interface LookupablePeerState for "lookupable peer states" added
- Looking up session ids in database basicly added
application/hub/exceptions/.htaccess -text
application/hub/exceptions/hub/.htaccess -text
application/hub/exceptions/hub/class_HubAlreadyAnnouncedException.php -text
+application/hub/exceptions/ids/.htaccess -text
+application/hub/exceptions/ids/class_InvalidSessionIdException.php -text
application/hub/exceptions/lists/.htaccess -text
application/hub/exceptions/lists/class_InvalidListHashException.php -text
application/hub/exceptions/lists/class_ListGroupAlreadyAddedException.php -text
application/hub/interfaces/lists/.htaccess -text
application/hub/interfaces/lists/class_Listable.php -text
application/hub/interfaces/lookup/.htaccess -text
+application/hub/interfaces/lookup/peer_states/.htaccess -text
+application/hub/interfaces/lookup/peer_states/class_LookupablePeerState.php -text
application/hub/interfaces/nodes/.htaccess -text
application/hub/interfaces/nodes/class_NodeHelper.php -text
application/hub/interfaces/package/.htaccess -text
--- /dev/null
+Deny from all
--- /dev/null
+<?php
+/**
+ * This exception is thrown when a hash is invalid
+ *
+ * @author Roland Haeder <webmaster@ship-simu.org>
+ * @version 0.0.0
+ * @copyright Copyright (c) 2007, 2008 Roland Haeder, 2009, 2010 Hub Developer Team
+ * @license GNU GPL 3.0 or any newer version
+ * @link http://www.ship-simu.org
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+class InvalidSessionIdException extends FrameworkException {
+ /**
+ * The super constructor for all exceptions
+ *
+ * @param $sessionId Session id
+ * @param $code Error code
+ * @return void
+ */
+ public function __construct ($sessionId, $code) {
+ // Construct the message
+ $message = sprintf("Session id %s is invalid.",
+ $sessionId
+ );
+
+ // Call parent exception constructor
+ parent::__construct($message, $code);
+ }
+}
+
+// [EOF]
+?>
--- /dev/null
+Deny from all
--- /dev/null
+<?php
+/**
+ * An interface for peer-state lookup tables
+ *
+ * @author Roland Haeder <webmaster@ship-simu.org>
+ * @version 0.0.0
+ * @copyright Copyright (c) 2007, 2008 Roland Haeder, 2009, 2010 Hub Developer Team
+ * @license GNU GPL 3.0 or any newer version
+ * @link http://www.ship-simu.org
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+interface LookupablePeerState extends Lookupable {
+ /**
+ * Checks wether given 'sender' is a new peer
+ *
+ * @param $packageData Raw package data
+ * @return $isNewPeer Wether 'sender' is a new peer to this node
+ */
+ function isSenderNewPeer (array $packageData);
+
+ /**
+ * Registers the given peer state and raw package data
+ *
+ * @param $stateInstance A PeerStateable class instance
+ * @param $packageData Valid package data array
+ * @return void
+ */
+ function registerPeerState (PeerStateable $stateInstance, array $packageData);
+}
+
+// [EOF]
+?>
* 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 NodeListDatabaseWrapper extends BaseDatabaseWrapper {
+class NodeListDatabaseWrapper extends BaseDatabaseWrapper implements Registerable {
// Table names
const DB_TABLE_NODE_LIST = 'node_list';
+ // Constants for column name
+ const DB_COLUMN_NODE_SESSION_ID = 'node_session_id';
+ const DB_COLUMN_NODE_IP_PORT = 'node_ipport';
+
/**
* Protected constructor
*
public final function getIndexKey () {
return $this->getDatabaseInstance()->getIndexKey();
}
+
+ /**
+ * Resolves a session id into an ip:port combination
+ *
+ * @param $sessionId A valid session id
+ * @return $recipient Recipient as ip:port combination
+ */
+ public function resolveIpPortBySessionId ($sessionId) {
+ // Set invalid ip:port combination
+ $recipient = 'invalid:invalid';
+
+ // Now get a search criteria instance
+ $searchInstance = ObjectFactory::createObjectByConfiguredName('search_criteria_class');
+
+ // Search for the node number zero which is hard-coded the default
+ $searchInstance->addCriteria(NodeListDatabaseWrapper::DB_COLUMN_NODE_SESSION_ID, 1);
+ $searchInstance->setLimit(1);
+
+ // Get a result back
+ $resultInstance = $this->doSelectByCriteria($searchInstance);
+
+ // Is it valid?
+ if ($resultInstance->next()) {
+ // Save the result instance in this class
+ $this->setResultInstance($resultInstance);
+
+ // Get the node id from result and set it
+ $recipient = $this->getField(NodeListDatabaseWrapper::DB_COLUMN_NODE_IP_PORT);
+ } // END - if
+
+ // Return result
+ return $recipient;
+ }
}
// [EOF]
const DB_TABLE_PEER_LOOKUP = 'peer_states';
// Constants for database column names
- const DB_COLUMN_PEER_IP = 'peer_ip';
+ const DB_COLUMN_PEER_IP = 'peer_ip';
/**
* Protected constructor
* @return $isNewPeer Wether 'sender' is a new peer to this node
*/
public function isSenderNewPeer (array $packageData) {
- // Get a search criteria instance
- $searchInstance = ObjectFactory::createObjectByConfiguredName('search_criteria_class');
+ // Is always new peer by default
+ $isNewPeer = true;
- // Add 'sender' as the peer's IP (this must already be looked up!)
- $searchInstance->addCriteria(self::DB_COLUMN_PEER_IP, $packageData['sender']);
- $searchInstance->setLimit(1);
+ // Remove session id > IP:port
+ $ipPort = HubTools::resolveSessionId($packageData[NetworkPackage::INDEX_PACKAGE_SENDER]);
- // Count the query
- $entries = $this->doSelectCountByCriteria($searchInstance);
+ // Is it not invalid:invalid?
+ if ($ipPort != 'invalid:invalid') {
+ // Get a search criteria instance
+ $searchInstance = ObjectFactory::createObjectByConfiguredName('search_criteria_class');
- // Is it there?
- $isNewPeer = ($entries === 0);
+ // Add 'sender' as the peer's IP address
+ $searchInstance->addCriteria(self::DB_COLUMN_PEER_IP, $ipPort);
+ $searchInstance->setLimit(1);
+
+ // Count the query
+ $entries = $this->doSelectCountByCriteria($searchInstance);
+
+ // Is it there?
+ $isNewPeer = ($entries === 0);
+ } // END - if
// Return the result
return $isNewPeer;
}
// For any purposes, return the state instance
- die(__METHOD__."\n");
return $stateInstance;
}
// Get a state from the resolver for this package
$stateInstance = $this->getResolverInstance()->resolveStateByPackage($this, $packageData);
- die('UNFINISHED:'.$stateInstance->__toString());
+ die('UNFINISHED:'.$stateInstance->__toString()."\n");
}
}
* 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 PeerStateLookupTable extends BaseLookupTable implements Lookupable {
+class PeerStateLookupTable extends BaseLookupTable implements LookupablePeerState {
/**
* Protected constructor
*
// Return it
return $isNewPeer;
}
+
+ /**
+ * Registers the given peer state and raw package data
+ *
+ * @param $stateInstance A PeerStateable class instance
+ * @param $packageData Valid package data array
+ * @return void
+ */
+ public function registerPeerState (PeerStateable $stateInstance, array $packageData) {
+ die(__METHOD__."\n");
+ }
}
// [EOF]
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
class HubTools extends BaseFrameworkSystem {
+ // Constants for exceptions
+ const EXCEPTION_SESSION_ID_IS_INVALID = 0x200;
+
+ /**
+ * Cache for session ids
+ */
+ private $sessionIdCache = array();
+
+ /**
+ * Length for session id (should be 32+salt_length
+ */
+ private $sessionIdLength = 0;
+
+ /**
+ * Self instance
+ */
+ private static $selfInstance = null;
+
/**
* Protected constructor
*
protected function __construct () {
// Call parent constructor
parent::__construct(__CLASS__);
+
+ // Init salt length
+ $this->sessionIdLength = 32 + $this->getConfigInstance()->getConfigEntry('salt_length');
}
/**
- * Resolves given session id into a ip:port string, if ip:port is set, it won't be translated
+ * Singleton getter for self instance
*
- * @param $sessionId Session id or ip:port string
- * @return $recipient Recipient as ip:port string
+ * @retuen $selfInstance An instance of this class
+ */
+ public final static function getInstance () {
+ // Is the instance set
+ if (is_null(self::$selfInstance)) {
+ // Then set it
+ self::$selfInstance = new HubTools();
+ } // END - if
+
+ // Return own instance
+ return self::$selfInstance;
+ }
+
+ /**
+ * Getter for session id length
+ *
+ * @return $sessionIdLength Length of session ids
+ */
+ protected final function getSessionIdLength () {
+ return $this->sessionIdLength;
+ }
+
+ /**
+ * Resolves a session id into an ip:port combination
+ *
+ * @param $sessionId A valid session id
+ * @return $recipient Recipient as ip:port combination
+ */
+ protected function resolveIpPortBySessionId ($sessionId) {
+ // Get a wrapper instance
+ $wrapperInstance = DatabaseWrapperFactory::createWrapperByConfiguredName('node_list_db_wrapper_class');
+
+ // And ask it for the session id
+ $recipient = $wrapperInstance->resolveIpPortBySessionId($sessionId);
+
+ // Return result
+ return $recipient;
+ }
+
+ /**
+ * Resolves given session id into an ip:port combination, if ip:port is set, it won't be translated
+ *
+ * @param $sessionId Session id or ip:port combination
+ * @return $recipient Recipient as ip:port combination
+ * @throws InvalidSessionIdException If the provided session id is invalid (and no ip:port combination)
*/
public static function resolveSessionId ($sessionId) {
+ // Get an own instance
+ $selfInstance = self::getInstance();
+
// Default is direct ip:port
$recipient = $sessionId;
// Does it match a direct ip:port? (hint: see www.regexlib.com for the regular expression)
if (!preg_match('/((?:2[0-5]{2}|1\d{2}|[1-9]\d|[1-9])\.(?:(?:2[0-5]{2}|1\d{2}|[1-9]\d|\d)\.){2}(?:2[0-5]{2}|1\d{2}|[1-9]\d|\d)):(\d|[1-9]\d|[1-9]\d{2,3}|[1-5]\d{4}|6[0-4]\d{3}|654\d{2}|655[0-2]\d|6553[0-5])/', $sessionId)) {
- die(__METHOD__.': sessionId=' . $sessionId . "\n");
+ // Is it in cache?
+ if (isset($selfInstance->sessionIdCache[$sessionId])) {
+ // Then use it
+ $recipient = $selfInstance->sessionIdCache[$sessionId];
+ } elseif (!preg_match('/([a-f0-9]{' . $selfInstance->getSessionIdLength() . '})/', $sessionId)) {
+ // Invalid session id
+ throw new InvalidSessionIdException($sessionId, self::EXCEPTION_SESSION_ID_IS_INVALID);
+ } else {
+ // Resolve it here
+ $recipient = $selfInstance->resolveIpPortBySessionId($sessionId);
+ }
} // END - if
+ // Output message
+ $selfInstance->debugOutput('HUB-TOOLS: Session id ' . $sessionId . ' resolved to ' . $recipient);
+
// Return it
return $recipient;
}