]> git.mxchange.org Git - hub.git/blobdiff - application/hub/main/package/class_NetworkPackage.php
'hub' project continued:
[hub.git] / application / hub / main / package / class_NetworkPackage.php
index bd094561cb783993cbe75523b799ec212d436b5c..4e480d3e492ef000243ac74914ad4dcb12c7269e 100644 (file)
@@ -35,7 +35,7 @@
  * 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
@@ -71,6 +71,7 @@ class NetworkPackage extends BaseFrameworkSystem implements Deliverable, Receiva
        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
@@ -79,20 +80,22 @@ class NetworkPackage extends BaseFrameworkSystem implements Deliverable, Receiva
        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 = '#';
 
@@ -200,6 +203,10 @@ class NetworkPackage extends BaseFrameworkSystem implements Deliverable, Receiva
                // 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;
        }
@@ -267,7 +274,10 @@ class NetworkPackage extends BaseFrameworkSystem implements Deliverable, Receiva
                } // 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;
@@ -368,9 +378,18 @@ class NetworkPackage extends BaseFrameworkSystem implements Deliverable, Receiva
 
                // 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.');
@@ -383,6 +402,9 @@ class NetworkPackage extends BaseFrameworkSystem implements Deliverable, Receiva
 
                // 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.');
        }
 
        /**
@@ -412,6 +434,27 @@ class NetworkPackage extends BaseFrameworkSystem implements Deliverable, Receiva
                $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.
@@ -450,7 +493,8 @@ class NetworkPackage extends BaseFrameworkSystem implements Deliverable, Receiva
                        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())
                ));
        }
 
@@ -548,7 +592,7 @@ class NetworkPackage extends BaseFrameworkSystem implements Deliverable, Receiva
                        $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);
@@ -790,6 +834,32 @@ class NetworkPackage extends BaseFrameworkSystem implements Deliverable, Receiva
                // 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]