* @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 . */ class PeerStateLookupDatabaseWrapper extends BaseDatabaseWrapper { // Exception constants const EXCEPTION_PEER_ALREADY_REGISTERED = 0x300; // Constants for database table names const DB_TABLE_PEER_LOOKUP = 'peer_states'; // Constants for database column names const DB_COLUMN_PEER_IP = 'peer_ip'; const DB_COLUMN_PEER_PORT = 'peer_port'; const DB_COLUMN_PEER_SESSION_ID = 'peer_session_id'; /** * Protected constructor * * @return void */ protected function __construct () { // Call parent constructor parent::__construct(__CLASS__); } /** * Creates an instance of this database wrapper by a provided user class * * @return $wrapperInstance An instance of the created wrapper class */ public final static function createPeerStateLookupDatabaseWrapper () { // Get a new instance $wrapperInstance = new PeerStateLookupDatabaseWrapper(); // Set (primary!) table name $wrapperInstance->setTableName(self::DB_TABLE_PEER_LOOKUP); // Return the instance return $wrapperInstance; } /** * Getter for index key * * @return $indexKey Index key */ public final function getIndexKey () { return $this->getDatabaseInstance()->getIndexKey(); } /** * Checks wether given 'sender' is a new peer * * @param $packageData Raw package data * @return $isNewPeer Wether 'sender' is a new peer to this node */ public function isSenderNewPeer (array $packageData) { // Is always new peer by default $isNewPeer = true; // Remove session id > IP:port $ipPort = HubTools::resolveSessionId($packageData[NetworkPackage::INDEX_PACKAGE_SENDER]); // Is it not invalid:invalid? if ($ipPort != 'invalid:invalid') { // Get a search criteria instance $searchInstance = ObjectFactory::createObjectByConfiguredName('search_criteria_class'); // 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; } /** * Registers a new peer with given package data. We use the session id from it. * * @param $packageData Raw package data * @param $socketResource A valid socket resource * @return void * @throws PeerAlreadyRegisteredException If a peer is already registered * @throws InvalidSocketException If the socket resource was invalid */ public function registerPeerByPackageData (array $packageData, $socketResource) { // Make sure only new peers can be registered with package data if (!$this->isSenderNewPeer($packageData)) { // Throw an exception because this should normally not happen throw new PeerAlreadyRegisteredException(array($this, $packageData), self::EXCEPTION_PEER_ALREADY_REGISTERED); } // END - if // Generate a dataset instance $dataSetInstance = ObjectFactory::createObjectByConfiguredName('dataset_criteria_class', array(self::DB_TABLE_PEER_LOOKUP)); // Session ids must be unique $dataSetInstance->setUniqueKey(self::DB_COLUMN_PEER_SESSION_ID); // Add session id $dataSetInstance->addCriteria(self::DB_COLUMN_PEER_SESSION_ID, $packageData[NetworkPackage::INDEX_PACKAGE_SENDER]); // Get peer name if (!socket_getpeername($socketResource, $peerName, $peerPort)) { // Get last error $lastError = socket_last_error($socketResource); // Doesn't work! throw new InvalidSocketException(array($this, gettype($socketResource), $lastError, socket_strerror($lastError)), BaseListener::EXCEPTION_INVALID_SOCKET); } // END - if // Add ip address and port $dataSetInstance->addCriteria(self::DB_COLUMN_PEER_IP , $peerName); $dataSetInstance->addCriteria(self::DB_COLUMN_PEER_PORT, $peerPort); // "Insert" the data set $this->getDatabaseInstance()->queryInsertDataSet($dataSetInstance); } /** * Purges old entries of given socket resource. We use the IP address from that resource. * * @param $socketResource A valid socket resource * @return void * @throws InvalidSocketException If the socket resource was invalid */ public function purgeOldEntriesBySocketResource ($socketResource) { // Get peer name if (!socket_getpeername($socketResource, $peerName, $peerPort)) { // Get last error $lastError = socket_last_error($socketResource); // Doesn't work! throw new InvalidSocketException(array($this, gettype($socketResource), $lastError, socket_strerror($lastError)), BaseListener::EXCEPTION_INVALID_SOCKET); } // END - if } } // [EOF] ?>