application/hub/interfaces/consumer/class_Consumer.php svneol=native#text/plain
application/hub/interfaces/cruncher/.htaccess svneol=native#text/plain
application/hub/interfaces/cruncher/class_CruncherHelper.php svneol=native#text/plain
+application/hub/interfaces/decoder/.htaccess -text svneol=unset#text/plain
+application/hub/interfaces/decoder/class_Decodeable.php svneol=native#text/plain
application/hub/interfaces/discovery/.htaccess -text svneol=unset#text/plain
application/hub/interfaces/discovery/class_DiscoverableRecipient.php svneol=native#text/plain
application/hub/interfaces/discovery/class_DiscoverableSocket.php svneol=native#text/plain
application/hub/main/database/wrapper/node/class_NodeListDatabaseWrapper.php svneol=native#text/plain
application/hub/main/database/wrapper/states/.htaccess svneol=native#text/plain
application/hub/main/database/wrapper/states/class_PeerStateLookupDatabaseWrapper.php svneol=native#text/plain
+application/hub/main/decoder/.htaccess -text svneol=unset#text/plain
+application/hub/main/decoder/class_ svneol=native#text/plain
+application/hub/main/decoder/package/.htaccess -text svneol=unset#text/plain
+application/hub/main/decoder/package/class_PackageDecoder.php svneol=native#text/plain
application/hub/main/decorators/.htaccess -text svneol=unset#text/plain
application/hub/main/discovery/.htaccess -text svneol=unset#text/plain
application/hub/main/discovery/class_BaseHubDiscovery.php svneol=native#text/plain
application/hub/main/tasks/hub/chunks/class_HubChunkAssemblerTask.php svneol=native#text/plain
application/hub/main/tasks/hub/class_Hub svneol=native#text/plain
application/hub/main/tasks/hub/class_HubSelfConnectTask.php svneol=native#text/plain
+application/hub/main/tasks/hub/decoder/.htaccess -text svneol=unset#text/plain
+application/hub/main/tasks/hub/decoder/class_HubPackageDecoderTask.php svneol=native#text/plain
application/hub/main/tasks/hub/ping/.htaccess -text svneol=unset#text/plain
application/hub/main/tasks/hub/ping/class_HubPingTask.php svneol=native#text/plain
application/hub/main/tasks/hub/update/.htaccess -text svneol=unset#text/plain
// CFG: STACKER-FINAL-CHUNKS-MAX-SIZE
$cfg->setConfigEntry('stacker_final_chunks_max_size', 100);
+// CFG: STACKER-CHUNK-RAW-DATA-MAX-SIZE
+$cfg->setConfigEntry('stacker_chunk_raw_data_max_size', 100);
+
+// CFG: STACKER-DECODED-PACKAGE-MAX-SIZE
+$cfg->setConfigEntry('stacker_decoded_package_max_size', 100);
+
// CFG: NEWS-MAIN-LIMIT
$cfg->setConfigEntry('news_main_limit', 5);
// CFG: HUB-CHUNK-ASSEMBLER-TASK-CLASS
$cfg->setConfigEntry('hub_chunk_assembler_task_class', 'HubChunkAssemblerTask');
+// CFG: HUB-PACKAGE-DECODER-TASK-CLASS
+$cfg->setConfigEntry('hub_package_decoder_task_class', 'HubPackageDecoderTask');
+
// CFG: TASK-NETWORK-PACKAGE-WRITER-STARTUP-DELAY
$cfg->setConfigEntry('task_network_package_writer_startup_delay', 2500);
// CFG: TASK-CHUNK-ASSEMBLER-STATUP-DELAY
$cfg->setConfigEntry('task_chunk_assembler_startup_delay', 1500);
+// CFG: TASK-PACKAGE-DECODER-STATUP-DELAY
+$cfg->setConfigEntry('task_package_decoder_startup_delay', 1300);
+
// CFG: TASK-CHUNK-ASSEMBLER-INTERVAL-DELAY
$cfg->setConfigEntry('task_chunk_assembler_interval_delay', 10);
+// CFG: TASK-PACKAGE-DECODER-INTERVAL-DELAY
+$cfg->setConfigEntry('task_package_decoder_interval_delay', 10);
+
// CFG: TASK-CHUNK-ASSEMBLER-MAX-RUNS
$cfg->setConfigEntry('task_chunk_assembler_max_runs', 0);
+// CFG: TASK-PACKAGE-DECODER-MAX-RUNS
+$cfg->setConfigEntry('task_package_decoder_max_runs', 0);
+
// CFG: TASK-LIST-CLASS
$cfg->setConfigEntry('task_list_class', 'TaskList');
// CFG: CHUNK-HANDLER-CLASS
$cfg->setConfigEntry('chunk_handler_class', 'ChunkHandler');
+// CFG: PACKAGE-DECODER-CLASS
+$cfg->setConfigEntry('package_decoder_class', 'PackageDecoder');
+
///////////////////////////////////////////////////////////////////////////////
// Peer states
///////////////////////////////////////////////////////////////////////////////
*/
public function __construct (array $messageArray, $code) {
// Construct the message
- $message = sprintf("[%s:%d] Unexpected package status %s!=%s detected, recipient=%s, sender=%s.",
+ $message = sprintf("[%s:%d] Unexpected package status %s!=%s detected, recipient=%s, sender=%s, signature=%s.",
$messageArray[0]->__toString(),
$this->getLine(),
$messageArray[1][NetworkPackage::PACKAGE_DATA_STATUS],
$messageArray[2],
$messageArray[1][NetworkPackage::PACKAGE_DATA_RECIPIENT],
- $messageArray[1][NetworkPackage::PACKAGE_DATA_SENDER]
+ $messageArray[1][NetworkPackage::PACKAGE_DATA_SENDER],
+ $messageArray[1][NetworkPackage::PACKAGE_DATA_SIGNATURE]
);
// Call parent exception constructor
--- /dev/null
+Deny from all
--- /dev/null
+<?php
+/**
+ * An interface for decoders
+ *
+ * @author Roland Haeder <webmaster@ship-simu.org>
+ * @version 0.0.0
+ * @copyright Copyright (c) 2007, 2008 Roland Haeder, 2009 - 2011 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 Decodeable extends FrameworkInterface {
+ /**
+ * Checks whether the assoziated stacker for raw package data has some entries left
+ *
+ * @return $unhandledDataLeft Whether some unhandled raw package data is left
+ */
+ function ifUnhandledRawPackageDataLeft ();
+
+ /**
+ * Handles raw package data by decoding it
+ *
+ * @return void
+ */
+ function handleRawPackageData ();
+
+ /**
+ * Checks whether decoded packages have arrived (for this peer)
+ *
+ * @return $ifDecodedPackagesLeft Whether decoded packages have arrived
+ */
+ function ifDeocedPackagesLeft ();
+
+ /**
+ * Handles received decoded packages internally (recipient is this node)
+ *
+ * @return void
+ */
+ function handleDecodedPackage ();
+}
+
+// [EOF]
+?>
*/
function discoverRecipients (array $packageData);
+ /**
+ * Tries to discover all recipients by given decoded package data.
+ *
+ * @param $decodedData Decoded raw package data array
+ * @return void
+ */
+ function discoverDecodedRecipients (array $decodedData);
+
/**
* "Getter" for recipient iterator
*
* @return void
*/
function assembleChunksFromFinalArray ();
+
+ /**
+ * Checks whether the raw package data has been assembled back together.
+ * This can be safely assumed when rawPackageData is not empty and the
+ * collection of all chunks is false (because initHandler() will reset it).
+ *
+ * @return $isRawPackageDataAvailable Whether raw package data is available
+ */
+ function ifRawPackageDataIsAvailable ();
+
+ /**
+ * Handles the finally assembled raw package data by feeding it into another
+ * stacker for further decoding/processing.
+ *
+ * @return void
+ */
+ function handledAssembledRawPackageData ();
}
// [EOF]
* @return void
*/
function addDecodedDataToIncomingStack (Networkable $handlerInstance);
+
+ /**
+ * "Decode" the package content. This method does also verify the attached hash
+ * against the real raw package data (that what the sender has sent).
+ *
+ * @param $rawPackageContent The raw package content to be "decoded"
+ * @return $decodedData The real package data that the sender has sent
+ */
+ function decodeRawContent ($rawPackageContent);
}
// [EOF]
*/
private $listenerPoolInstance = NULL;
+ /**
+ * Fragmenter instance
+ */
+ private $fragmenterInstance = NULL;
+
+ /**
+ * Decoder instance
+ */
+ private $decoderInstance = NULL;
+
/**
* Protected constructor
*
return $this->listenerPoolInstance;
}
+ /**
+ * Setter for fragmenter instance
+ *
+ * @param $fragmenterInstance A Fragmentable instance
+ * @return void
+ */
+ protected final function setFragmenterInstance (Fragmentable $fragmenterInstance) {
+ $this->fragmenterInstance = $fragmenterInstance;
+ }
+
+ /**
+ * Getter for fragmenter instance
+ *
+ * @return $fragmenterInstance A Fragmentable instance
+ */
+ protected final function getFragmenterInstance () {
+ return $this->fragmenterInstance;
+ }
+
+ /**
+ * Setter for decoder instance
+ *
+ * @param $decoderInstance A Decodeable instance
+ * @return void
+ */
+ protected final function setDecoderInstance (Decodeable $decoderInstance) {
+ $this->decoderInstance = $decoderInstance;
+ }
+
+ /**
+ * Getter for decoder instance
+ *
+ * @return $decoderInstance A Decodeable instance
+ */
+ protected final function getDecoderInstance () {
+ return $this->decoderInstance;
+ }
+
/**
* Constructs a callable method name from given socket error code. If the
* method is not found, a generic one is used.
* @throws UnsupportedSocketErrorHandlerException If the error handler is not implemented
*/
protected function getSocketErrorHandlerFromCode ($errorCode) {
- // Set NULL, so everyone is forced to implement socket error handlers
- $handlerName = NULL;
-
- // Temporary create a possible name from translated error code
+ // Create a name from translated error code
$handlerName = 'socketError' . $this->convertToClassName($this->translateSocketErrorCodeToName($errorCode)) . 'Handler';
// Is the call-back method there?
// Get a visitor instance
$visitorInstance = ObjectFactory::createObjectByConfiguredName('shutdown_socket_visitor_class');
+ // Debug output
+ $this->debugOutput('HUB-SYSTEM:' . $this->__toString() . ': visitorInstance=' . $visitorInstance->__toString());
+
// Call the visitor
$this->accept($visitorInstance);
}
// Get a visitor instance
$visitorInstance = ObjectFactory::createObjectByConfiguredName('half_shutdown_socket_visitor_class');
+ // Debug output
+ $this->debugOutput('HUB-SYSTEM:' . $this->__toString() . ': visitorInstance=' . $visitorInstance->__toString());
+
// Call the visitor
$this->accept($visitorInstance);
}
* 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 NetworkPackageCompressorDecorator extends BaseFrameworkSystem implements Compressor {
+class NetworkPackageCompressorDecorator extends BaseHubSystem implements Compressor {
/**
* Protected constructor
*
--- /dev/null
+Deny from all
--- /dev/null
+<?php
+/**
+ * A ??? decoder class
+ *
+ * @author Roland Haeder <webmaster@ship-simu.org>
+ * @version 0.0.0
+ * @copyright Copyright (c) 2007, 2008 Roland Haeder, 2009 - 2011 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 ???Decoder extends BaseDecoder implements Decodeable {
+ /**
+ * Protected constructor
+ *
+ * @return void
+ */
+ protected function __construct () {
+ // Call parent constructor
+ parent::__construct(__CLASS__);
+ }
+
+ /**
+ * Creates an instance of this class
+ *
+ * @return $decoderInstance An instance of a Decodeable class
+ */
+ public final static function create???Decoder () {
+ // Get new instance
+ $decoderInstance = new ???Decoder();
+
+ // Return the prepared instance
+ return $decoderInstance;
+ }
+}
+
+// [EOF]
+?>
--- /dev/null
+<?php
+/**
+ * A general Decoder class
+ *
+ * @author Roland Haeder <webmaster@ship-simu.org>
+ * @version 0.0.0
+ * @copyright Copyright (c) 2007, 2008 Roland Haeder, 2009 - 2011 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 BaseDecoder extends BaseHubSystem {
+ /**
+ * Protected constructor
+ *
+ * @param $className Name of the class
+ * @return void
+ */
+ protected function __construct ($className) {
+ // Call parent constructor
+ parent::__construct($className);
+ }
+}
+
+// [EOF]
+?>
--- /dev/null
+Deny from all
--- /dev/null
+<?php
+/**
+ * A Package decoder class
+ *
+ * @author Roland Haeder <webmaster@ship-simu.org>
+ * @version 0.0.0
+ * @copyright Copyright (c) 2007, 2008 Roland Haeder, 2009 - 2011 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 PackageDecoder extends BaseDecoder implements Decodeable {
+ /**
+ * Name for stacker for received packages
+ */
+ const STACKER_NAME_DECODED_PACKAGE = 'decoded_package';
+
+ /**
+ * Protected constructor
+ *
+ * @return void
+ */
+ protected function __construct () {
+ // Call parent constructor
+ parent::__construct(__CLASS__);
+ }
+
+ /**
+ * Creates an instance of this class
+ *
+ * @param $stackerInstance An instance of a Stackable class
+ * @return $decoderInstance An instance of a Decodeable class
+ */
+ public final static function createPackageDecoder (Stackable $stackerInstance) {
+ // Get new instance
+ $decoderInstance = new PackageDecoder();
+
+ // Init stacker for received packages
+ $stackerInstance->initStacker(self::STACKER_NAME_DECODED_PACKAGE);
+
+ // Set the stacker instance here
+ $decoderInstance->setStackerInstance($stackerInstance);
+
+ // Get a singleton network package instance
+ $packageInstance = NetworkPackageFactory::createNetworkPackageInstance();
+
+ // And set it in this decoder
+ $decoderInstance->setPackageInstance($packageInstance);
+
+ // Return the prepared instance
+ return $decoderInstance;
+ }
+
+ /**
+ * Checks whether the assoziated stacker for raw package data has some entries left
+ *
+ * @return $unhandledDataLeft Whether some unhandled raw package data is left
+ */
+ public function ifUnhandledRawPackageDataLeft () {
+ // Check it
+ $unhandledDataLeft = (!$this->getStackerInstance()->isStackEmpty(ChunkHandler::STACKER_NAME_ASSEMBLED_RAW_DATA));
+
+ // Return it
+ return $unhandledDataLeft;
+ }
+
+ /**
+ * Handles raw package data by decoding it
+ *
+ * @return void
+ */
+ public function handleRawPackageData () {
+ // Assert on it to make sure the next popNamed() call won't throw an exception
+ assert($this->ifUnhandledRawPackageDataLeft());
+
+ // "Pop" the next raw package content
+ $rawPackageContent = $this->getStackerInstance()->popNamed(ChunkHandler::STACKER_NAME_ASSEMBLED_RAW_DATA);
+
+ // "Decode" the raw package content by using the NetworkPackage instance
+ $decodedData = $this->getPackageInstance()->decodeRawContent($rawPackageContent);
+
+ // Next get a recipient-discovery instance
+ $discoveryInstance = PackageDiscoveryFactory::createPackageDiscoveryInstance();
+
+ // ... then disover all recipient (might be only one), this package may shall be forwarded
+ $discoveryInstance->discoverDecodedRecipients($decodedData);
+
+ // Check for 'recipient' field (the 'sender' field and others are ignored here)
+ if ($discoveryInstance->isRecipientListEmpty()) {
+ // The recipient is this node so next stack it on 'decoded_package'
+ $this->getStackerInstance()->pushNamed(self::STACKER_NAME_DECODED_PACKAGE, $decodedData);
+ } else {
+ // Forward the package to the next node
+ $this->getPackageInstance()->forwardDecodedPackage($decodedData);
+ }
+ }
+
+ /**
+ * Checks whether decoded packages have arrived (for this peer)
+ *
+ * @return $ifDecodedPackagesLeft Whether decoded packages have arrived
+ */
+ public function ifDeocedPackagesLeft () {
+ // Check it ...
+ $ifDecodedPackagesLeft = (!$this->getStackerInstance()->isStackEmpty(self::STACKER_NAME_DECODED_PACKAGE));
+
+ // ... return it
+ return $ifDecodedPackagesLeft;
+ }
+
+ /**
+ * Handles received decoded packages internally (recipient is this node)
+ *
+ * @return void
+ */
+ public function handleDecodedPackage () {
+ // Get the next entry (assoziative array)
+ $decodedData = $this->getStackerInstance()->popNamed(self::STACKER_NAME_DECODED_PACKAGE);
+
+ // Handle it
+ die('decodedData='.print_r($decodedData,true));
+ }
+}
+
+// [EOF]
+?>
// Get an instance of this class
$discoveryInstance = new PackageRecipientDiscovery();
- // Output debug message
- $discoveryInstance->debugOutput('RECIPIENT-DISCOVERY: Initialized.');
-
// Get recipients list instance and set it
$listInstance = RecipientListFactory::createRecipientListInstance();
$discoveryInstance->setListInstance($listInstance);
+ // Output debug message
+ $discoveryInstance->debugOutput('RECIPIENT-DISCOVERY: Initialized.');
+
// Return the prepared instance
return $discoveryInstance;
}
} // END - switch
}
+ /**
+ * Tries to discover all recipients by given decoded package data.
+ *
+ * @param $decodedData Decoded raw package data array
+ * @return void
+ * @todo Add some validation of recipient field, e.g. ip:port is found
+ */
+ public function discoverDecodedRecipients (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()) {
+ /*
+ * Is same as own external 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: */ $this->debugOutput('RECIPIENT-DISCOVERY: Recipient ' . $recipient[0] . ' matches own ip (' . HubTools::determineOwnExternalIp() . ')');
+ } else {
+ // Debug output (may flood)
+ /* NOISY-DEBUG: */ $this->debugOutput('RECIPIENT-DISCOVERY: Recipient ' . $recipient[0] . ' is different than own ip (' . HubTools::determineOwnExternalIp() . '), 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;
}
+ /**
+ * 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.
// Get a socket resource from our factory (if succeeded)
$socketResource = SocketFactory::createSocketFromPackageData($packageData, $protocolName);
-
- // This succeeded, so change the state to 'CONNECTED'
} catch (SocketConnectionException $e) {
// The connection fails of being established, so log it away
- $this->debugOutput('SOCKET-DISCOVERY: ' . $e->__toString() . ',message=' . $e->getMessage());
+ $this->debugOutput('SOCKET-DISCOVERY: Caught ' . $e->__toString() . ',message=' . $e->getMessage());
}
} // END - if
// Register it as well
$handlerInstance->registerTask('chunk_assembler', $taskInstance);
+ // Generate package decoder task
+ $taskInstance = ObjectFactory::createObjectByConfiguredName('hub_package_decoder_task_class');
+
+ // Register it as well
+ $handlerInstance->registerTask('package_decoder', $taskInstance);
+
// Query handler instance
$handlerInstance->registerTask('query_handler', $nodeInstance->getQueryConnectorInstance());
* Stacker for chunks with final EOP
*/
const STACKER_NAME_CHUNKS_WITH_FINAL_EOP = 'final_chunks';
+ const STACKER_NAME_ASSEMBLED_RAW_DATA = 'chunk_raw_data';
/**
* Chunk splits:
/**
* The final array for assembling the original package back together
*/
- private $finalPackageChunks = array(
- // Array for package content
- 'content' => array(),
- // ... and for the hashes
- 'hashes' => array(),
- // ... marker for that the final array is complete for assembling all chunks
- 'is_complete' => false
- );
+ private $finalPackageChunks = array();
+
+ /**
+ * Array of chunk hashes
+ */
+ private $chunkHashes = array();
+
+ /**
+ * Raw EOP chunk data in an array:
+ *
+ * 0 = Final hash,
+ * 1 = Hash of last chunk
+ */
+ private $eopChunk = array();
+
+ /**
+ * Raw package data
+ */
+ private $rawPackageData = '';
/**
* Protected constructor
// Set handler name
$this->setHandlerName('chunk');
+
+ // Initialize handler
+ $this->initHandler();
}
/**
// Init all stacker
$stackerInstance->initStacker(self::STACKER_NAME_CHUNKS_WITH_FINAL_EOP);
+ $stackerInstance->initStacker(self::STACKER_NAME_ASSEMBLED_RAW_DATA);
// Set the stacker in this handler
$handlerInstance->setStackerInstance($stackerInstance);
// ... and set it in this handler
$handlerInstance->setCryptoInstance($cryptoInstance);
+ // Get a fragmenter instance for later verification of serial numbers (e.g. if all are received)
+ $fragmenterInstance = FragmenterFactory::createFragmenterInstance('package');
+
+ // Set it in this handler
+ $handlerInstance->setFragmenterInstance($fragmenterInstance);
+
// Return the prepared instance
return $handlerInstance;
}
+ /**
+ * Initializes the handler
+ *
+ * @return void
+ */
+ private function initHandler () {
+ // Init finalPackageChunks
+ $this->finalPackageChunks = array(
+ // Array for package content
+ 'content' => array(),
+ // ... and for the hashes
+ 'hashes' => array(),
+ // ... marker for that the final array is complete for assembling all chunks
+ 'is_complete' => false,
+ // ... steps done to assemble all chunks
+ 'assemble_steps' => 0,
+ );
+
+ // ... chunkHashes:
+ $this->chunkHashes = array();
+
+ // ... eopChunk:
+ $this->eopChunk = array(
+ 0 => 'INVALID',
+ 1 => 'INVALID',
+ );
+ }
+
/**
* Checks whether the hash generated from package content is the same ("valid") as given
*
$this->finalPackageChunks['is_complete'] = true;
}
+ /**
+ * Sorts the chunks array by using the serial number as a sorting key. In
+ * most situations a call of ksort() is enough to accomblish this. So this
+ * method may only call ksort() on the chunks array.
+ *
+ * This method sorts 'content' and 'hashes' so both must have used the
+ * serial numbers as array indexes.
+ *
+ * @return void
+ */
+ private function sortChunksArray () {
+ // Sort 'content' first
+ ksort($this->finalPackageChunks['content']);
+
+ // ... then 'hashes'
+ ksort($this->finalPackageChunks['hashes']);
+ }
+
+ /**
+ * Prepares the package assemble by removing last chunks (last shall be
+ * hash chunk, pre-last shall be EOP chunk) and verify that all serial
+ * numbers are valid (same as PackageFragmenter class would generate).
+ *
+ * @return void
+ */
+ private function preparePackageAssmble () {
+ // Make sure both arrays have same count (this however should always be true)
+ assert(count($this->finalPackageChunks['hashes']) == count($this->finalPackageChunks['content']));
+
+ /*
+ * Remove last element (hash chunk) from 'hashes'. This hash will never
+ * be needed, so ignore it.
+ */
+ array_pop($this->finalPackageChunks['hashes']);
+
+ // ... and from 'content' as well but save it for later use
+ $this->chunkHashes = explode(PackageFragmenter::CHUNK_HASH_SEPARATOR, substr(array_pop($this->finalPackageChunks['content']), strlen(PackageFragmenter::HASH_CHUNK_IDENTIFIER)));
+
+ // Remove EOP chunk and keep a copy of it
+ array_pop($this->finalPackageChunks['hashes']);
+ $this->eopChunk = explode(PackageFragmenter::CHUNK_HASH_SEPARATOR, substr(array_pop($this->finalPackageChunks['content']), strlen(PackageFragmenter::END_OF_PACKAGE_IDENTIFIER)));
+
+ // Verify all serial numbers
+ $this->verifyChunkSerialNumbers();
+ }
+
+ /**
+ * Verifies all chunk serial numbers by using a freshly initialized
+ * fragmenter instance. Do ALWAYS sort the array and array_pop() the hash
+ * chunk before calling this method to avoid re-requests of many chunks.
+ *
+ * @return void
+ */
+ private function verifyChunkSerialNumbers () {
+ // Reset the serial number generator
+ $this->getFragmenterInstance()->resetSerialNumber();
+
+ // "Walk" through all (content) chunks
+ foreach ($this->finalPackageChunks['content'] as $serialNumber=>$content) {
+ // Get next serial number
+ $nextSerial = $this->getFragmenterInstance()->getNextHexSerialNumber();
+
+ // Debug output
+ //* NOISY-DEBUG */ $this->debugOutput('CHUNK-HANDLER: serialNumber=' . $serialNumber . ',nextSerial=' . $nextSerial);
+
+ // Is it not the same? Then re-request it
+ if ($serialNumber != $nextSerial) {
+ // This is invalid, so remove it
+ unset($this->finalPackageChunks['content'][$serialNumber]);
+ unset($this->finalPackageChunks['hashes'][$serialNumber]);
+
+ // And re-request it with valid serial number (and hash chunk)
+ $this->rerequestChunkBySerialNumber($nextSerial);
+ } // END - if
+ } // END - foreach
+ }
+
+ /**
+ * Assembles and verifies ("final check") chunks back together to the
+ * original package (raw data for the start). This method should only be
+ * called AFTER the EOP and final-chunk chunk have been removed.
+ *
+ * @return void
+ */
+ private function assembleAllChunksToPackage () {
+ // If chunkHashes is not filled, don't continue
+ assert(count($this->chunkHashes) > 0);
+
+ // Init raw package data string
+ $this->rawPackageData = '';
+
+ // That went well, so start assembling all chunks
+ foreach ($this->finalPackageChunks['content'] as $serialNumber=>$content) {
+ // Is this chunk valid? This should be the case
+ assert($this->isChunkHashValid(array(
+ self::CHUNK_SPLITS_INDEX_HASH => $this->finalPackageChunks['hashes'][$serialNumber],
+ self::CHUNK_SPLITS_INDEX_RAW_DATA => $content
+ )));
+
+ // ... and is also in the hash chunk?
+ assert(in_array($this->finalPackageChunks['hashes'][$serialNumber], $this->chunkHashes));
+
+ // Verification okay, add it to the raw data
+ $this->rawPackageData .= $content;
+ } // END - foreach
+
+ // Debug output
+ //* NOISY-DEBUG: */ $this->debugOutput('CHUNK-HANDLER: eopChunk[1]=' . $this->eopChunk[1] . ',' . chr(10) . 'index=' . (count($this->chunkHashes) - 2) . ',' . chr(10) . 'chunkHashes='.print_r($this->chunkHashes,true));
+
+ // The last chunk hash must match with the one from eopChunk[1]
+ assert($this->eopChunk[1] == $this->chunkHashes[count($this->chunkHashes) - 2]);
+ }
+
+ /**
+ * Verifies the finally assembled raw package data by comparing it against
+ * the final hash.
+ *
+ * @return void
+ */
+ private function verifyRawPackageData () {
+ // Hash the raw package data for final verification
+ $finalHash = $this->getCryptoInstance()->hashString($this->rawPackageData, $this->eopChunk[0], false);
+
+ // Is it the same?
+ assert($finalHash == $this->eopChunk[0]);
+ }
+
/**
* Adds all chunks if the last one verifies as a 'final chunk'.
*
// Make sure the final array is really completed
assert($this->ifUnassembledChunksAvailable());
- $this->partialStub('Please implement this method.');
+ // Count up stepping
+ $this->finalPackageChunks['assemble_steps']++;
+
+ // Do the next step
+ switch ($this->finalPackageChunks['assemble_steps']) {
+ case 1: // Sort the chunks array (the serial number shall act as a sorting key)
+ $this->sortChunksArray();
+ break;
+
+ case 2: // Prepare the assemble by removing last two indexes
+ $this->preparePackageAssmble();
+ break;
+
+ case 3: // Assemble all chunks back together to the original package
+ $this->assembleAllChunksToPackage();
+ break;
+
+ case 4: // Verify the raw data by hashing it again
+ $this->verifyRawPackageData();
+ break;
+
+ case 5: // Re-initialize handler to reset it to the old state
+ $this->initHandler();
+ break;
+
+ default: // Invalid step found
+ $this->debugOutput('CHUNK-HANDLER: Invalid step ' . $this->finalPackageChunks['assemble_steps'] . ' detected.');
+ break;
+ } // END - switch
+ }
+
+ /**
+ * Checks whether the raw package data has been assembled back together.
+ * This can be safely assumed when rawPackageData is not empty and the
+ * collection of all chunks is false (because initHandler() will reset it).
+ *
+ * @return $isRawPackageDataAvailable Whether raw package data is available
+ */
+ public function ifRawPackageDataIsAvailable () {
+ // Check it
+ $isRawPackageDataAvailable = ((!empty($this->rawPackageData)) && (!$this->ifUnassembledChunksAvailable()));
+
+ // Return it
+ return $isRawPackageDataAvailable;
+ }
+
+ /**
+ * Handles the finally assembled raw package data by feeding it into another
+ * stacker for further decoding/processing.
+ *
+ * @return void
+ */
+ public function handledAssembledRawPackageData () {
+ // Assert to make sure that there is raw package data available
+ assert($this->ifRawPackageDataIsAvailable());
+
+ // Then feed it into the next stacker
+ $this->getStackerInstance()->pushNamed(self::STACKER_NAME_ASSEMBLED_RAW_DATA, $this->rawPackageData);
+
+ // ... and reset it
+ $this->rawPackageData = '';
}
}
$socketResource = $this->getSocketResource();
$timeout = $this->getConfigInstance()->getConfigEntry('socket_timeout_seconds');
+ // Debug output
+ $this->debugOutput('CONNECTION-HELPER: Trying to connect to ' . $recipientData[0] . ':' . $recipientData[1] . ' with socketResource[' . gettype($socketResource) . ']=' . $socketResource . ' ...');
+
// Try to connect until it is connected
while ($isConnected = !@socket_connect($socketResource, $recipientData[0], $recipientData[1])) {
// Get last socket error
// Add the hash to the index
$this->listIndex[] = $hash;
- //* DEBUG: */ print $groupName.'/'.count($this->listIndex).chr(10);
+ //* DEBUG: */ print $groupName.'/'.$this->count().chr(10);
// Now add the entry to the list
$this->listEntries[$hash] = $entry;
* 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 NetworkPackage extends BaseFrameworkSystem implements Deliverable, Receivable, Registerable, Visitable {
+class NetworkPackage extends BaseHubSystem implements Deliverable, Receivable, Registerable, Visitable {
/**
* Package mask for compressing package data:
* 0: Compressor extension
const INDEX_PACKAGE_RECIPIENT = 1;
const INDEX_PACKAGE_CONTENT = 2;
const INDEX_PACKAGE_STATUS = 3;
+ const INDEX_PACKAGE_SIGNATURE = 4;
/**
* Named array elements for package data
const PACKAGE_DATA_RECIPIENT = 'recipient';
const PACKAGE_DATA_CONTENT = 'content';
const PACKAGE_DATA_STATUS = 'status';
+ const PACKAGE_DATA_SIGNATURE = 'signature';
/**
* All package status
*/
const PACKAGE_STATUS_NEW = 'new';
const PACKAGE_STATUS_FAILED = 'failed';
+ const PACKAGE_STATUS_DECODED = 'decoded';
/**
- * Tags SEPARATOR
+ * Tags separator
*/
const PACKAGE_TAGS_SEPARATOR = ';';
/**
- * Raw package data SEPARATOR
+ * Raw package data separator
*/
const PACKAGE_DATA_SEPARATOR = '#';
// Set it in this package
$packageInstance->setVisitorInstance($visitorInstance);
+ // Get crypto instance and set it in this package
+ $cryptoInstance = ObjectFactory::createObjectByConfiguredName('crypto_class');
+ $packageInstance->setCryptoInstance($cryptoInstance);
+
// Return the prepared instance
return $packageInstance;
}
} // END - if
// Pop the entry (it should be it)
- $this->getStackerInstance()->popNamed($stackerName);
+ $nextData = $this->getStackerInstance()->popNamed($stackerName);
+
+ // Compare both arrays
+ assert($nextData[self::PACKAGE_DATA_SIGNATURE] == $packageData[self::PACKAGE_DATA_SIGNATURE]);
// Temporary set the new status
$packageData[self::PACKAGE_DATA_STATUS] = $newStatus;
// Is it not there?
if ((is_resource($socketResource)) && (!$registryInstance->isSocketRegistered($helperInstance, $socketResource))) {
+ // Debug message
+ $this->debugOutput('PACKAGE: Registering socket ' . $socketResource . ' ...');
+
// Then register it
$registryInstance->registerSocket($helperInstance, $socketResource, $packageData);
- } // END - if
+ } elseif (!$helperInstance->getStateInstance()->isPeerStateConnected()) {
+ // Is not connected, then we cannot send
+ $this->debugOutput('PACKAGE: Unexpected peer state ' . $helperInstance->getStateInstance()->__toString() . ' detected.');
+
+ // Shutdown the socket
+ $this->shutdownSocket($socketResource);
+ }
// Debug message
//* NOISY-DEBUG: */ $this->debugOutput('NETWORK-PACKAGE: Reached line ' . __LINE__ . ' after isSocketRegistered() has been called.');
// Enqueue it again on the out-going queue, the connection is up and working at this point
$this->getStackerInstance()->pushNamed(self::STACKER_NAME_OUTGOING, $packageData);
+
+ // Debug message
+ //* NOISY-DEBUG: */ $this->debugOutput('NETWORK-PACKAGE: Reached line ' . __LINE__ . ' after pushNamed() has been called.');
}
/**
$this->storeUnsentBytesInBackBuffer($packageData, $sentBytes);
}
+ /**
+ * Generates a signature for given raw package content and sender id
+ *
+ * @param $content Raw package data
+ * @param $senderId Sender id to generate a signature for
+ * @return $signature Signature as BASE64-encoded string
+ */
+ private function generatePackageSignature ($content, $senderId) {
+ // ash content and sender id together, use md5() as last algo
+ $hash = md5($this->getCryptoInstance()->hashString($senderId . $content));
+
+ // Encrypt the content again with the hash as a key
+ $encryptedContent = $this->getCryptoInstance()->encryptString($content, $hash);
+
+ // Encode it with BASE64
+ $signature = base64_encode($encryptedContent);
+
+ // Return it
+ return $signature;
+ }
+
/**
* "Enqueues" raw content into this delivery class by reading the raw content
* from given template instance and pushing it on the 'undeclared' stack.
self::PACKAGE_DATA_SENDER => $nodeInstance->getSessionId(),
self::PACKAGE_DATA_RECIPIENT => $helperInstance->getRecipientType(),
self::PACKAGE_DATA_CONTENT => $content,
- self::PACKAGE_DATA_STATUS => self::PACKAGE_STATUS_NEW
+ self::PACKAGE_DATA_STATUS => self::PACKAGE_STATUS_NEW,
+ self::PACKAGE_DATA_SIGNATURE => $this->generatePackageSignature($content, $nodeInstance->getSessionId())
));
}
$this->getStackerInstance()->popNamed(self::STACKER_NAME_DECLARED);
} catch (InvalidStateException $e) {
// The state is not excepected (shall be 'connected')
- $this->debugOutput('PACKAGE: Caught exception ' . $e->__toString() . ' with message=' . $e->getMessage());
+ $this->debugOutput('PACKAGE: Caught ' . $e->__toString() . ',message=' . $e->getMessage());
// Mark the package with status failed
$this->changePackageStatus($packageData, self::STACKER_NAME_DECLARED, self::PACKAGE_STATUS_FAILED);
// Remove this entry
$this->getStackerInstance()->popNamed(self::STACKER_NAME_DECLARED);
}
+
+ /**
+ * "Decode" the package content into the same array when it was sent.
+ *
+ * @param $rawPackageContent The raw package content to be "decoded"
+ * @return $decodedData An array with 'sender', 'recipient', 'content' and 'status' elements
+ */
+ public function decodeRawContent ($rawPackageContent) {
+ // Use the separator '#' to "decode" it
+ $decodedArray = explode(self::PACKAGE_DATA_SEPARATOR, $rawPackageContent);
+
+ // Assert on count (should be always 3)
+ assert(count($decodedArray) == 3);
+
+ // Create 'decodedData' array with all assoziative array elements
+ $decodedData = array(
+ self::PACKAGE_DATA_SENDER => $decodedArray[self::INDEX_PACKAGE_SENDER],
+ self::PACKAGE_DATA_RECIPIENT => $decodedArray[self::INDEX_PACKAGE_RECIPIENT],
+ self::PACKAGE_DATA_CONTENT => $decodedArray[self::INDEX_PACKAGE_CONTENT],
+ self::PACKAGE_DATA_STATUS => self::PACKAGE_STATUS_DECODED,
+ self::PACKAGE_DATA_SIGNATURE => $this->generatePackageSignature($decodedArray[self::INDEX_PACKAGE_CONTENT], $decodedArray[self::INDEX_PACKAGE_SENDER])
+ );
+
+ // And return it
+ return $decodedData;
+ }
}
// [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 PackageFragmenter extends BaseFrameworkSystem implements Fragmentable, Registerable {
+class PackageFragmenter extends BaseHubSystem implements Fragmentable, Registerable {
/**
* Cached chunk size in bits
*/
return $hash;
}
- /**
- * "Getter" for the next hexadecimal-encoded serial number
- *
- * @return $encodedSerialNumber The next hexadecimal-encoded serial number
- */
- private function getNextHexSerialNumber () {
- // Assert on maximum serial number length
- assert($this->serialNumber <= $this->maxSerialNumber);
-
- // Encode the current serial number
- $encodedSerialNumber = $this->dec2Hex($this->serialNumber, self::MAX_SERIAL_LENGTH);
-
- // Count one up
- $this->serialNumber++;
-
- // Return the encoded serial number
- return $encodedSerialNumber;
- }
-
/**
* Appends an end-of-package chunk to the chunk list for given chunk and
* final hash. As of 23-March-2012 the format of this chunk will be as any
* regular one to keep things easy (KISS) in ChunkHandler class.
*
- * @param $chunkHash Last chunk's hash
+ * @param $lastChunk Last chunk raw data
* @param $finalHash Final hash for raw (unencoded) data
* @return void
*/
- private function appendEndOfPackageChunk ($chunkHash, $finalHash) {
+ private function appendEndOfPackageChunk ($lastChunk, $finalHash) {
// Generate end-of-package marker
$chunkData =
self::END_OF_PACKAGE_IDENTIFIER .
$finalHash . self::CHUNK_HASH_SEPARATOR .
- $chunkHash;
+ $this->generateHashFromRawData($lastChunk);
// Add it as regular chunk
$this->addChunkData($finalHash, $chunkData);
// Init variables
$chunkHash = '';
+ $chunkData = '';
// Now split it up
for ($idx = 0; $idx < strlen($rawData); $idx += $dataChunkSize) {
//* NOISY-DEBUG: */ $this->debugOutput('FRAGMENTER: Raw data of ' . strlen($rawData) . ' bytes has been fragmented into ' . count($this->chunks[$finalHash]) . ' chunk(s).');
// Add end-of-package chunk
- $this->appendEndOfPackageChunk($chunkHash, $finalHash);
+ $this->appendEndOfPackageChunk($chunkData, $finalHash);
}
/**
} // END - for
}
+ /**
+ * "Getter" for the next hexadecimal-encoded serial number
+ *
+ * @return $encodedSerialNumber The next hexadecimal-encoded serial number
+ */
+ public function getNextHexSerialNumber () {
+ // Assert on maximum serial number length
+ assert($this->serialNumber <= $this->maxSerialNumber);
+
+ // Encode the current serial number
+ $encodedSerialNumber = $this->dec2Hex($this->serialNumber, self::MAX_SERIAL_LENGTH);
+
+ // Count one up
+ $this->serialNumber++;
+
+ // Return the encoded serial number
+ return $encodedSerialNumber;
+ }
+
/**
* This method does "implode" the given package data array into one long
* string, splits it into small chunks, adds a serial number and checksum
// Return the chunk array
return $rawDataChunk;
}
+
+ /**
+ * Resets the serial number to zero
+ *
+ * @return void
+ */
+ public function resetSerialNumber () {
+ $this->serialNumber = 0;
+ }
}
// [EOF]
self::$connectionStatistics[$helperInstance->getProtocol()][$helperInstance->__toString()]['retry_count']++;
}
- // Create/update 'last_update' for later purging
+ // Create/update 'last_update' for purging
+ // @TODO last_update is not being used at the moment
self::$connectionStatistics[$helperInstance->getProtocol()][$helperInstance->__toString()]['last_update'] = time();
}
}
* 'final array' for last verification.
*/
$this->getHandlerInstance()->handleAvailableChunksWithFinal();
+ } elseif ($this->getHandlerInstance()->ifRawPackageDataIsAvailable()) {
+ /*
+ * The final raw package data is back together again. So feed it
+ * into the next stack for further decoding/processing
+ */
+ $this->getHandlerInstance()->handledAssembledRawPackageData();
}
}
}
--- /dev/null
+Deny from all
--- /dev/null
+<?php
+/**
+ * A PackageDecoder hub-task
+ *
+ * @author Roland Haeder <webmaster@ship-simu.org>
+ * @version 0.0.0
+ * @copyright Copyright (c) 2007, 2008 Roland Haeder, 2009 - 2011 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 HubPackageDecoderTask extends BaseTask implements Taskable, Visitable {
+ /**
+ * Protected constructor
+ *
+ * @return void
+ */
+ protected function __construct () {
+ // Call parent constructor
+ parent::__construct(__CLASS__);
+ }
+
+ /**
+ * Creates an instance of this class
+ *
+ * @return $taskInstance An instance of a Visitable class
+ */
+ public final static function createHubPackageDecoderTask () {
+ // Get new instance
+ $taskInstance = new HubPackageDecoderTask();
+
+ // Get a chunk handler instance
+ $handlerInstance = ChunkHandlerFactory::createChunkHandlerInstance();
+
+ // Get the stacker from it, we don't need the handler here
+ $stackerInstance = $handlerInstance->getStackerInstance();
+
+ // Get a decoder instance
+ $decoderInstance = ObjectFactory::createObjectByConfiguredName('package_decoder_class', array($stackerInstance));
+
+ // ... and also set the decoder instance here
+ $taskInstance->setDecoderInstance($decoderInstance);
+
+ // Return the prepared instance
+ return $taskInstance;
+ }
+
+ /**
+ * Accepts the visitor to process the visit "request"
+ *
+ * @param $visitorInstance An instance of a Visitor class
+ * @return void
+ * @todo Maybe visit some sub-objects
+ */
+ public function accept (Visitor $visitorInstance) {
+ // Visit this task
+ $visitorInstance->visitTask($this);
+ }
+
+ /**
+ * Executes the task
+ *
+ * @return void
+ */
+ public function executeTask () {
+ // Check if the stacker has some entries left
+ if ($this->getDecoderInstance()->ifUnhandledRawPackageDataLeft()) {
+ // Then handle it
+ $this->getDecoderInstance()->handleRawPackageData();
+ } elseif ($this->getDecoderInstance()->ifDeocedPackagesLeft()) {
+ // Some decoded packages have arrived (for this peer)
+ $this->getDecoderInstance()->handleDecodedPackage();
+ }
+ }
+}
+
+// [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 HubTools extends BaseFrameworkSystem {
+class HubTools extends BaseHubSystem {
// Constants for exceptions
const EXCEPTION_SESSION_ID_IS_INVALID = 0x200;
const EXCEPTION_HOSTNAME_NOT_FOUND = 0x201;
./application/hub/interfaces/helper/connections/class_ConnectionHelper.php:38: * @todo We may want to implement a filter for ease notification of other objects like our pool
./application/hub/interfaces/helper/messages/class_MessageHelper.php:10: * @todo Please find another name for this interface
./application/hub/interfaces/nodes/class_NodeHelper.php:10: * @todo We need to find a better name for this interface
-./application/hub/main/class_BaseHubSystem.php:331: // @TODO On some systems it is 134, on some 107?
+./application/hub/main/class_BaseHubSystem.php:376: // @TODO On some systems it is 134, on some 107?
./application/hub/main/commands/console/class_HubConsoleChatCommand.php:107: * @todo Should we add some more filters?
./application/hub/main/commands/console/class_HubConsoleChatCommand.php:58: * @todo Try to create a ChatActivationTask or so
./application/hub/main/commands/console/class_HubConsoleCruncherCommand.php:107: * @todo Should we add some more filters?
./application/hub/main/cruncher/mcrypt/class_HubMcryptCruncher.php:98: // @TODO Implement this method
./application/hub/main/database/wrapper/states/class_PeerStateLookupDatabaseWrapper.php:177: * @todo Unfinished area
./application/hub/main/database/wrapper/states/class_PeerStateLookupDatabaseWrapper.php:219: * @todo Unfinished area
+./application/hub/main/discovery/package/class_PackageRecipientDiscovery.php:100: * @todo Add some validation of recipient field, e.g. ip:port is found
./application/hub/main/discovery/socket/class_PackageSocketDiscovery.php:102: // @TODO We may need some logging here
./application/hub/main/factories/socket/class_SocketFactory.php:10: * @todo Find an interface for hub helper
./application/hub/main/filter/bootstrap/chat/class_ChatBootstrapGenericActivationFilter.php:54: * @todo Maybe we want to do somthing more here?
./application/hub/main/nodes/regular/class_HubRegularNode.php:58: * @todo Implement this method
./application/hub/main/nodes/regular/class_HubRegularNode.php:68: * @todo Unfinished method
./application/hub/main/nodes/regular/class_HubRegularNode.php:91: // @TODO Add some filters here
-./application/hub/main/package/class_NetworkPackage.php:237: * @todo $helperInstance is unused
./application/hub/main/package/class_NetworkPackage.php:23: * @todo Needs to add functionality for handling the object's type
-./application/hub/main/package/class_NetworkPackage.php:241: // @TODO crc32() is very weak, but it needs to be fast
-./application/hub/main/package/class_NetworkPackage.php:404: // @TODO We may want to do somthing more here?
-./application/hub/main/package/class_NetworkPackage.php:510: // @TODO Add some logging here
-./application/hub/main/package/class_NetworkPackage.php:536: // @TODO Add some logging here
-./application/hub/main/package/class_NetworkPackage.php:640: // @TODO Add some logging here
-./application/hub/main/package/class_NetworkPackage.php:739: // @TODO Add some content here
-./application/hub/main/package/class_NetworkPackage.php:778: * @todo This may be enchanced for outgoing packages?
+./application/hub/main/package/class_NetworkPackage.php:244: * @todo $helperInstance is unused
+./application/hub/main/package/class_NetworkPackage.php:248: // @TODO crc32() is very weak, but it needs to be fast
+./application/hub/main/package/class_NetworkPackage.php:426: // @TODO We may want to do somthing more here?
+./application/hub/main/package/class_NetworkPackage.php:554: // @TODO Add some logging here
+./application/hub/main/package/class_NetworkPackage.php:580: // @TODO Add some logging here
+./application/hub/main/package/class_NetworkPackage.php:684: // @TODO Add some logging here
+./application/hub/main/package/class_NetworkPackage.php:783: // @TODO Add some content here
+./application/hub/main/package/class_NetworkPackage.php:822: * @todo This may be enchanced for outgoing packages?
./application/hub/main/package/fragmenter/class_PackageFragmenter.php:274: * @todo Implement a way to send non-announcement packages with extra-salt
-./application/hub/main/package/fragmenter/class_PackageFragmenter.php:441: * @todo $helperInstance is unused
+./application/hub/main/package/fragmenter/class_PackageFragmenter.php:442: * @todo $helperInstance is unused
./application/hub/main/producer/cruncher/keys/class_CruncherKeyProducer.php:106: // @TODO Do something with it
./application/hub/main/producer/cruncher/keys/class_CruncherKeyProducer.php:62: * @todo Find something for init phase of this key producer
./application/hub/main/producer/cruncher/keys/class_CruncherKeyProducer.php:72: * @todo ~30% done
./application/hub/main/resolver/state/peer/class_PeerStateResolver.php:59: * @todo ~30% done
./application/hub/main/states/node/init/class_NodeInitState.php:60: * @todo We might want to move some calls to this method to fill it with life
./application/hub/main/statistics/connection/class_ConnectionStatisticsHelper.php:11: * @todo Find an interface for hub helper
+./application/hub/main/statistics/connection/class_ConnectionStatisticsHelper.php:98: // @TODO last_update is not being used at the moment
./application/hub/main/streams/raw_data/input/class_RawDataInputStream.php:57: * @todo Do we need to do something more here?
./application/hub/main/streams/raw_data/output/class_RawDataOutputStream.php:53: * @todo Do we need to do something more here?
./application/hub/main/tasks/chat/class_ChatTelnetListenerTask.php:53: * @todo Maybe visit some sub-objects
./application/hub/main/tasks/hub/class_HubSelfConnectTask.php:53: * @todo 0%
./application/hub/main/tasks/hub/class_HubSocketListenerTask.php:63: // @TODO Do we need to visit this task? $visitorInstance->visitTask($this);
./application/hub/main/tasks/hub/class_HubSocketListenerTask.php:70: * @todo 0% done
+./application/hub/main/tasks/hub/decoder/class_HubPackageDecoderTask.php:65: * @todo Maybe visit some sub-objects
./application/hub/main/tasks/hub/ping/class_HubPingTask.php:63: * @todo Also visit some sub-objects?
./application/hub/main/tasks/hub/ping/class_HubPingTask.php:74: * @todo 0% done
./application/hub/main/tasks/hub/update/class_HubUpdateCheckTask.php:53: * @todo 0%
./inc/classes/exceptions/main/class_MissingMethodException.php:13: * @todo Try to rewrite user/guest login classes and mark this exception as deprecated
./inc/classes/exceptions/main/class_NoConfigEntryException.php:10: * @todo Rename this class to NoFoundEntryException
./inc/classes/interfaces/class_FrameworkInterface.php:11: * @todo Find a better name for this interface
-./inc/classes/main/class_BaseFrameworkSystem.php:1301: * @todo Write a logging mechanism for productive mode
-./inc/classes/main/class_BaseFrameworkSystem.php:1315: // @TODO Finish this part!
+./inc/classes/main/class_BaseFrameworkSystem.php:1306: * @todo Write a logging mechanism for productive mode
+./inc/classes/main/class_BaseFrameworkSystem.php:1320: // @TODO Finish this part!
./inc/classes/main/class_BaseFrameworkSystem.php:195: // @todo Try to clean these constants up
./inc/classes/main/class_BaseFrameworkSystem.php:465: * @todo SearchableResult and UpdateableResult shall have a super interface to use here
./inc/classes/main/commands/web/class_WebLoginAreaCommand.php:64: * @todo Add some stuff here: Some personal data, app/game related data