]> git.mxchange.org Git - hub.git/commitdiff
Decoding of raw package message basicly finished, external public ip now included...
authorRoland Häder <roland@mxchange.org>
Sat, 5 May 2012 23:52:59 +0000 (23:52 +0000)
committerRoland Häder <roland@mxchange.org>
Sat, 5 May 2012 23:52:59 +0000 (23:52 +0000)
.gitattributes
application/hub/config.php
application/hub/exceptions/package/class_InvalidDataChecksumException.php [new file with mode: 0644]
application/hub/interfaces/package/class_Receivable.php
application/hub/main/database/wrapper/node/class_NodeListDatabaseWrapper.php
application/hub/main/decoder/package/class_PackageDecoder.php
application/hub/main/listener/class_BaseListener.php
application/hub/main/nodes/class_BaseHubNode.php
application/hub/main/package/class_NetworkPackage.php
application/hub/main/tools/class_HubTools.php

index 6382e8404151d01afc81fd852e50c9fb161c707d..5e40db56ea4ac1eaf670297404679086efdfaf2f 100644 (file)
@@ -18,6 +18,7 @@ application/hub/exceptions/lists/class_ListGroupAlreadyAddedException.php svneol
 application/hub/exceptions/lists/class_NoListGroupException.php svneol=native#text/plain
 application/hub/exceptions/package/.htaccess -text svneol=unset#text/plain
 application/hub/exceptions/package/class_FinalChunkVerificationException.php svneol=native#text/plain
+application/hub/exceptions/package/class_InvalidDataChecksumException.php svneol=native#text/plain
 application/hub/exceptions/package/class_UnexpectedPackageStatusException.php -text
 application/hub/exceptions/package/class_UnsupportedPackageCodeHandlerException.php svneol=native#text/plain
 application/hub/exceptions/peer/.htaccess -text svneol=unset#text/plain
index b1505b3528171fa3dc7d246096c6c35efadb2495..8353a61c57b20e41bb58fec5ea2e38ed0c4ba327 100644 (file)
@@ -549,6 +549,9 @@ $cfg->setConfigEntry('session_id', '');
 // CFG: EXTERNAL-IP
 $cfg->setConfigEntry('external_ip', '');
 
+// CFG: NODE-STATUS
+$cfg->setConfigEntry('node_status', 'invalid');
+
 // CFG: PACKAGE-FRAGMENTER-CLASS
 $cfg->setConfigEntry('package_fragmenter_class', 'PackageFragmenter');
 
diff --git a/application/hub/exceptions/package/class_InvalidDataChecksumException.php b/application/hub/exceptions/package/class_InvalidDataChecksumException.php
new file mode 100644 (file)
index 0000000..0d93da8
--- /dev/null
@@ -0,0 +1,48 @@
+<?php
+/**
+ * This exception is thrown when the checksum (sometimes called "hash") of the
+ * package data (aka "message" emcoded with BASE64) is not valid.
+ *
+ * @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 InvalidDataChecksumException extends FrameworkException {
+       /**
+        * The super constructor for all exceptions
+        *
+        * @param       $messageArray   Error message array
+        * @param       $code                   Error code
+        * @return      void
+        */
+       public function __construct (array $messageArray, $code) {
+               // Construct the message
+               $message = sprintf("[%s:%d] The checksum %s doesn't match the checksum of the content: %s",
+                       $messageArray[0]->__toString(),
+                       $this->getLine(),
+                       $messageArray[0]->getHashFromContentSessionId($messageArray[1], $messageArray[2][NetworkPackage::PACKAGE_DATA_SENDER]),
+                       $messageArray[1][NetworkPackage::PACKAGE_CONTENT_CHECKSUM]
+               );
+
+               // Call parent exception constructor
+               parent::__construct($message, $code);
+       }
+}
+
+// [EOF]
+?>
index fe1be45b895eadb05c8e6c8c5454669fcdc6b74c..72149c53269968f40db00a83e0c4146583434eef 100644 (file)
@@ -92,6 +92,14 @@ interface Receivable extends FrameworkInterface {
         * @return      void
         */
        function handleAssemblerPendingData ();
+
+       /**
+        * Handles decoded data for this node
+        *
+        * @param       $decodedData    An array with decoded raw package data
+        * @return      void
+        */
+       function handleDecodedData (array $decodedData);
 }
 
 // [EOF]
index 8b0214c3c7676ae5f7347d9ccbe81ee0604a03a4..c9d47e4f6c12e65a5bac1d66c059fbfe5bb147f2 100644 (file)
@@ -90,6 +90,39 @@ class NodeListDatabaseWrapper extends BaseDatabaseWrapper implements Registerabl
                // Return result
                return $recipient;
        }
+
+       /**
+        * Resolves a ip:port combination into a session id
+        *
+        * @param       $ipPort         Ip:port combination
+        * @return      $sessionId      A valid session id
+        */
+       public function resolveSessionIdByIpPort ($ipPort) {
+               // Set invalid session id as default
+               $sessionId = 'invalid';
+
+               // Now get a search criteria instance
+               $searchInstance = ObjectFactory::createObjectByConfiguredName('search_criteria_class');
+
+               // Search for the node session id
+               $searchInstance->addCriteria(NodeListDatabaseWrapper::DB_COLUMN_NODE_IP_PORT, $ipPort);
+               $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 session from result
+                       $sessionId = $this->getField(NodeListDatabaseWrapper::DB_COLUMN_NODE_SESSION_ID);
+               } // END - if
+
+               // Return result
+               return $sessionId;
+       }
 }
 
 // [EOF]
index 4d663454bbba622448e56812b499b1c5829e8475..93f3c14cc3074894845920eeee46cda58b6bac02 100644 (file)
@@ -130,7 +130,7 @@ class PackageDecoder extends BaseDecoder implements Decodeable {
                $decodedData = $this->getStackerInstance()->popNamed(self::STACKER_NAME_DECODED_PACKAGE);
 
                // Handle it
-               die('decodedData='.print_r($decodedData,true));
+               $this->getPackageInstance()->handleDecodedData($decodedData);
        }
 }
 
index fdae47c8d2e28178fd1617e65ee0c155728e1967..2906ef426e8626db91e40de8687410008c3853ed 100644 (file)
@@ -31,6 +31,7 @@ class BaseListener extends BaseHubSystem implements Visitable {
        const EXCEPTION_UNEXPECTED_PACKAGE_STATUS        = 0xa05;
        const EXCEPTION_UNSUPPORTED_PACKAGE_CODE_HANDLER = 0xa06;
        const EXCEPTION_FINAL_CHUNK_VERIFICATION         = 0xa07;
+       const EXCEPTION_INVALID_DATA_CHECKSUM            = 0xa08;
 
        /**
         * Used protocol (Default: invalid, which is indeed invalid...)
index bbd63bf6a98a74e37396506ed18d48fb2c3036cd..bbec7957e99ca9cbf3283d06582b3c4bd5556943 100644 (file)
@@ -390,6 +390,9 @@ class BaseHubNode extends BaseHubSystem implements Updateable {
                        throw new HubAlreadyAnnouncedException($this, self::EXCEPTION_HUB_ALREADY_ANNOUNCED);
                } // END - if
 
+               // Set some dummy configuration entries, e.g. node_status
+               $this->getConfigInstance()->setConfigEntry('node_status', $this->getStateInstance()->getStateName());
+
                // Debug output
                $this->debugOutput('HUB-Announcement: START (taskInstance=' . $taskInstance->__toString(). ')');
 
@@ -399,9 +402,6 @@ class BaseHubNode extends BaseHubSystem implements Updateable {
                // Load the announcement descriptor
                $helperInstance->loadDescriptorXml();
 
-               // Set some dummy configuration entries, e.g. node_status
-               $this->getConfigInstance()->setConfigEntry('node_status', $this->getStateInstance()->getStateName());
-
                // Compile all variables
                $helperInstance->getTemplateInstance()->compileConfigInVariables();
 
index 87be5cb99043ab4edc18595b3e0d524f8fb790a9..67cc10b7957039bfe334f02352f060d49773ce12 100644 (file)
@@ -52,7 +52,13 @@ class NetworkPackage extends BaseHubSystem implements Deliverable, Receivable, R
        const PACKAGE_MASK_SEPARATOR = '^';
 
        /**
-        * SEPARATOR for checksum
+        * Size of an array created by invoking
+        * explode(NetworkPackage::PACKAGE_MASK_SEPARATOR, $content).
+        */
+       const PACKAGE_CONTENT_ARRAY_SIZE = 4;
+
+       /**
+        * Separator for checksum
         */
        const PACKAGE_CHECKSUM_SEPARATOR = '_';
 
@@ -73,6 +79,19 @@ class NetworkPackage extends BaseHubSystem implements Deliverable, Receivable, R
        const INDEX_PACKAGE_STATUS    = 3;
        const INDEX_PACKAGE_SIGNATURE = 4;
 
+       /**
+        * Size of the decoded data array ('status' is not included)
+        */
+       const DECODED_DATA_ARRAY_SIZE = 4;
+
+       /**
+        * Named array elements for decoded package content
+        */
+       const PACKAGE_CONTENT_EXTENSION = 'compressor';
+       const PACKAGE_CONTENT_MESSAGE   = 'message';
+       const PACKAGE_CONTENT_TAGS      = 'tags';
+       const PACKAGE_CONTENT_CHECKSUM  = 'checksum';
+
        /**
         * Named array elements for package data
         */
@@ -114,11 +133,6 @@ class NetworkPackage extends BaseHubSystem implements Deliverable, Receivable, R
         */
        const TCP_PACKAGE_SIZE = 512;
 
-       /**
-        * Size of the decoded data array
-        */
-       const DECODED_DATA_ARRAY_SIZE = 4;
-
        /**************************************************************************
         *                    Stacker for out-going packages                      *
         **************************************************************************/
@@ -244,12 +258,10 @@ class NetworkPackage extends BaseHubSystem implements Deliverable, Receivable, R
        }
 
        /**
-        * "Getter" for hash from given content and helper instance
+        * "Getter" for hash from given content
         *
-        * @param       $content                        Raw package content
-        * @param       $helperInstance         An instance of a HelpableHub class
-        * @param       $nodeInstance           An instance of a NodeHelper class
-        * @return      $hash                           Hash for given package content
+        * @param       $content        Raw package content
+        * @return      $hash           Hash for given package content
         */
        private function getHashFromContent ($content) {
                // Debug message
@@ -269,6 +281,24 @@ class NetworkPackage extends BaseHubSystem implements Deliverable, Receivable, R
                return $hash;
        }
 
+       /**
+        * Checks whether the checksum (sometimes called "hash") is the same
+        *
+        * @param       $decodedContent         Package raw content
+        * @param       $decodedData            Whole raw package data array
+        * @return      $isChecksumValid        Whether the checksum is the same
+        */
+       private function isChecksumValid (array $decodedContent, array $decodedData) {
+               // Get checksum
+               $checksum = $this->getHashFromContentSessionId($decodedContent, $decodedData[self::PACKAGE_DATA_SENDER]);
+
+               // Is it the same?
+               $isChecksumValid = ($checksum == $decodedContent[self::PACKAGE_CONTENT_CHECKSUM]);
+
+               // Return it
+               return $isChecksumValid;
+       }
+
        /**
         * Change the package with given status in given stack
         *
@@ -287,7 +317,7 @@ class NetworkPackage extends BaseHubSystem implements Deliverable, Receivable, R
                // Pop the entry (it should be it)
                $nextData = $this->getStackerInstance()->popNamed($stackerName);
 
-               // Compare both arrays
+               // Compare both signatures
                assert($nextData[self::PACKAGE_DATA_SIGNATURE] == $packageData[self::PACKAGE_DATA_SIGNATURE]);
 
                // Temporary set the new status
@@ -297,6 +327,31 @@ class NetworkPackage extends BaseHubSystem implements Deliverable, Receivable, R
                $this->getStackerInstance()->pushNamed($stackerName, $packageData);
        }
 
+       /**
+        * "Getter" for hash from given content and sender's session id
+        *
+        * @param       $decodedContent         Decoded package content
+        * @param       $sessionId                      Session id of the sender
+        * @return      $hash                           Hash for given package content
+        */
+       public function getHashFromContentSessionId (array $decodedContent, $sessionId) {
+               // Debug message
+               //* NOISY-DEBUG: */ $this->debugOutput('NETWORK-PACKAGE: content[md5]=' . md5($decodedContent[self::PACKAGE_CONTENT_MESSAGE]) . ',sender=' . $sessionId . ',compressor=' . $decodedContent[self::PACKAGE_CONTENT_EXTENSION]);
+
+               // Create the hash
+               // @TODO crc32() is very weak, but it needs to be fast
+               $hash = crc32(
+                       $decodedContent[self::PACKAGE_CONTENT_MESSAGE] .
+                       self::PACKAGE_CHECKSUM_SEPARATOR .
+                       $sessionId .
+                       self::PACKAGE_CHECKSUM_SEPARATOR .
+                       $decodedContent[self::PACKAGE_CONTENT_EXTENSION]
+               );
+
+               // And return it
+               return $hash;
+       }
+
        ///////////////////////////////////////////////////////////////////////////
        //                   Delivering packages / raw data
        ///////////////////////////////////////////////////////////////////////////
@@ -470,6 +525,23 @@ class NetworkPackage extends BaseHubSystem implements Deliverable, Receivable, R
                return $signature;
        }
 
+       /**
+        * Checks whether the signature of given package data is 'valid', here that
+        * means it is the same or not.
+        *
+        * @param       $decodedArray           An array with 'decoded' (explode() was mostly called) data
+        * @return      $isSignatureValid       Whether the signature is valid
+        * @todo        Unfinished area, signature are currently not supported
+        */
+       private function isPackageSignatureValid (array $decodedArray) {
+               // Generate the signature of comparing it
+               $signature = $this->generatePackageSignature($decodedArray[self::INDEX_PACKAGE_CONTENT], $decodedArray[self::INDEX_PACKAGE_SENDER]);
+
+               // Is it the same?
+               //$isSignatureValid = 
+               die('signature='.$signature.print_r($decodedArray,true));
+       }
+
        /**
         * "Enqueues" raw content into this delivery class by reading the raw content
         * from given template instance and pushing it on the 'undeclared' stack.
@@ -884,18 +956,71 @@ class NetworkPackage extends BaseHubSystem implements Deliverable, Receivable, R
                // Assert on count (should be always 3)
                assert(count($decodedArray) == self::DECODED_DATA_ARRAY_SIZE);
 
-               // Create 'decodedData' array with all assoziative array elements
+               // Generate the signature of comparing it
+               /*
+                * @todo Unsupported feature commented out
+               if (!$this->isPackageSignatureValid($decodedArray)) {
+                       // Is not valid, so throw an exception here
+                       die('INVALID SIG! UNDER CONSTRUCTION!' . chr(10));
+               } // END - if
+               */
+
+               /*
+                * Create 'decodedData' array with all assoziative array elements,
+                * except signature.
+                */
                $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])
+                       self::PACKAGE_DATA_STATUS    => self::PACKAGE_STATUS_DECODED
                );
 
                // And return it
                return $decodedData;
        }
+
+       /**
+        * Handles decoded data for this node by "decoding" the 'content' part of
+        * it. Again this method uses explode() for the "decoding" process.
+        *
+        * @param       $decodedData    An array with decoded raw package data
+        * @return      void
+        * @throws      InvalidDataChecksumException    If the checksum doesn't match
+        */
+       public function handleDecodedData (array $decodedData) {
+               /*
+                * "Decode" the package's content by a simple explode() call, for
+                * details of the array elements, see comments for constant
+                * PACKAGE_MASK.
+                */
+               $decodedContent = explode(self::PACKAGE_MASK_SEPARATOR, $decodedData[self::PACKAGE_DATA_CONTENT]);
+
+               // Assert on array count for a very basic validation
+               assert(count($decodedContent) == self::PACKAGE_CONTENT_ARRAY_SIZE);
+
+               // Convert the indexed array into an associative array
+               $decodedContent = array(
+                       // Compressor's extension used to compress the data
+                       self::PACKAGE_CONTENT_EXTENSION => $decodedContent[self::INDEX_COMPRESSOR_EXTENSION],
+                       // Package data (aka "message") in BASE64-decoded form
+                       self::PACKAGE_CONTENT_MESSAGE   => base64_decode($decodedContent[self::INDEX_PACKAGE_DATA]),
+                       // Tags as an indexed array for "tagging" the message
+                       self::PACKAGE_CONTENT_TAGS      => explode(self::PACKAGE_TAGS_SEPARATOR, $decodedContent[self::INDEX_TAGS]),
+                       // Checksum of the _decoded_ data
+                       self::PACKAGE_CONTENT_CHECKSUM  => $decodedContent[self::INDEX_CHECKSUM]
+               );
+
+               // Is the checksum valid?
+               if (!$this->isChecksumValid($decodedContent, $decodedData)) {
+                       // Is not the same, so throw an exception here
+                       throw new InvalidDataChecksumException(array($this, $decodedContent, $decodedData), BaseListener::EXCEPTION_INVALID_DATA_CHECKSUM);
+               } // END - if
+
+               // It is the same, then decompress it, the original message is than fully decoded
+               $decodedContent[self::PACKAGE_CONTENT_MESSAGE] = $this->getCompressorInstance()->decompressStream($decodedContent[self::PACKAGE_CONTENT_MESSAGE]);
+               die('decodedContent='.print_r($decodedContent,true));
+       }
 }
 
 // [EOF]
index c7063ece5f8eab7bef7e2d11c40156276a11d207..2580a0582b7f7683efb766e378e283f26e70b6b1 100644 (file)
@@ -108,6 +108,23 @@ class HubTools extends BaseHubSystem {
                return $recipient;
        }
 
+       /**
+        * Resolves a ip:port combination into a session id
+        *
+        * @param       $ipPort         Ip:port combination
+        * @return      $sessionId      Valid session id
+        */
+       public static function resolveSessionIdByIpPort ($ipPort) {
+               // Get a wrapper instance
+               $wrapperInstance = DatabaseWrapperFactory::createWrapperByConfiguredName('node_list_db_wrapper_class');
+
+               // And ask it for the session id
+               $sessionId = $wrapperInstance->resolveSessionIdByIpPort($ipPort);
+
+               // Return result
+               return $sessionId;
+       }
+
        /**
         * Resolves given session id into an ip:port combination, if ip:port is set, it won't be translated
         *