* 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]