use Org\Shipsimu\Hub\Locator\Node\LocateableNode;
use Org\Shipsimu\Hub\Network\Deliver\Deliverable;
use Org\Shipsimu\Hub\Network\Package\Assembler\Assembler;
+use Org\Shipsimu\Hub\Network\Package\DeliverablePackage;
use Org\Shipsimu\Hub\Network\Package\Fragment\Fragmentable;
use Org\Shipsimu\Hub\Network\Receive\Receivable;
use Org\Shipsimu\Hub\Pool\Poolable;
/**
* A network package handler instance
*/
- private $packageInstance = NULL;
+ private $packageHandlerInstance = NULL;
/**
* A Receivable instance
*/
private $sourceInstance = NULL;
+ /**
+ * Package instance
+ */
+ private $packageInstance = NULL;
+
/**
* Name of used protocol
*/
/* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('HUB-SYSTEM: data()=%d - CALLED!', strlen($data)));
// Determine it
- $isset = ((substr($data, 0, strlen(HandleableRawData::STREAM_START_MARKER)) == HandleableRawData::STREAM_START_MARKER) && (substr($data, -1 * strlen(HandleableRawData::STREAM_END_MARKER), strlen(HandleableRawData::STREAM_END_MARKER)) == HandleableRawData::STREAM_END_MARKER));
+ $isset = (
+ (
+ substr($data, 0, strlen(HandleableRawData::STREAM_START_MARKER)) == HandleableRawData::STREAM_START_MARKER
+ ) && (
+ substr($data, -1 * strlen(HandleableRawData::STREAM_END_MARKER), strlen(HandleableRawData::STREAM_END_MARKER)) == HandleableRawData::STREAM_END_MARKER
+ )
+ );
// ... and return it
return $isset;
/**
* Setter for network package handler instance
*
- * @param $packageInstance The network package instance we shall set
+ * @param $packageHandlerInstance The network package instance we shall set
* @return void
*/
- protected final function setPackageInstance (Deliverable $packageInstance) {
- $this->packageInstance = $packageInstance;
+ protected final function setPackageHandlerInstance (Deliverable $packageHandlerInstance) {
+ $this->packageHandlerInstance = $packageHandlerInstance;
}
/**
* Getter for network package handler instance
*
- * @return $packageInstance The network package handler instance we shall set
+ * @return $packageHandlerInstance The network package handler instance we shall set
*/
- protected final function getPackageInstance () {
- return $this->packageInstance;
+ protected final function getPackageHandlerInstance () {
+ return $this->packageHandlerInstance;
}
/**
return $this->sourceInstance;
}
+ /**
+ * Setter for package instance
+ *
+ * @param $packageInstance An instance of a DeliverablePackage instance
+ * @return void
+ */
+ public final function setPackageInstance (DeliverablePackage $packageInstance) {
+ $this->packageInstance = $packageInstance;
+ }
+
+ /**
+ * Getter for package instance
+ *
+ * @return $packageInstance An instance of a DeliverablePackage instance
+ */
+ public function getPackageInstance () {
+ return $this->packageInstance;
+ }
+
}
use Org\Shipsimu\Hub\Information\ShareableInfo;
use Org\Shipsimu\Hub\Listener\BaseListener;
use Org\Shipsimu\Hub\Listener\Listenable;
-use Org\Shipsimu\Hub\Network\Package\NetworkPackage;
+use Org\Shipsimu\Hub\Network\Package\DeliverablePackage;
+use Org\Shipsimu\Hub\Network\Package\NetworkPackageHandler;
// Import framework stuff
use Org\Mxchange\CoreFramework\Factory\ObjectFactory;
/**
* Socket protocol:
* - 'tcp' for TCP/IPv4 connections
- * - 'file' for Unix* file-based sockets
+ * - 'file' for Uni* file-based sockets
*/
private $socketProtocol = StorableSocket::SOCKET_PROTOCOL_INVALID;
* Creates an instance of this Container class and prepares it for usage
*
* @param $socketResource A valid socket resource
- * @param $socketProtocol Socket protocol
- * @param $packageData Raw package data
+ * @param $socketProtocol Socket protocol (TCP, UDP, file)
+ * @param $packageInstance An instance of a DeliverablePackage class
* @return $socketInstance An instance of this Container class
* @throws InvalidArgumentException If socket type is not set in $packageData array
*/
- public static final function createSocketContainer ($socketResource, $socketProtocol, array $packageData) {
+ public static final function createSocketContainer ($socketResource, $socketProtocol, DeliverablePackage $packageInstance) {
// Trace message
- /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('SOCKET: socketResource=%s,socketProtocol=%s,packageData()=%d - CALLED!', $socketResource, $socketProtocol, count($packageData)));
- //* DEBUG-PRINT: */ printf('[%s:%d]: packageData=%s', __METHOD__, __LINE__, print_r($packageData, TRUE));
-
- // Socket type must always be there
- if (!isset($packageData[StorableSocket::SOCKET_ARRAY_INDEX_TYPE])) {
- // Abort here
- throw new InvalidArgumentException(sprintf('Array packageData does not contain "%s".', StorableSocket::SOCKET_ARRAY_INDEX_TYPE));
- } // END - if
+ /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('SOCKET: socketResource[%s]=%s,socketProtocol=%s,packageInstance[]=%s - CALLED!', gettype($socketResource), $socketResource, $socketProtocol, gettype($packageInstance)));
+ //* DEBUG-PRINT: */ printf('[%s:%d]: packageInstance=%s', __METHOD__, __LINE__, print_r($packageInstance, TRUE));
// Get a new instance
$socketInstance = new SocketContainer();
// Trace message
- /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('SOCKET: socketResource=%s,socketProtocol=%s,packageData[%s]=%s', $socketResource, $socketProtocol, StorableSocket::SOCKET_ARRAY_INDEX_TYPE, $packageData[StorableSocket::SOCKET_ARRAY_INDEX_TYPE]));
+ /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('SOCKET: socketResource=%s,socketProtocol=%s,packageInstance->socketType=%s', $socketResource, $socketProtocol, $packageInstance->getSocketType()));
// Set protocol
$socketInstance->setSocketProtocol($socketProtocol);
- // Remove unneeded entries
- unset($packageData[NetworkPackage::PACKAGE_DATA_CONTENT]);
- unset($packageData[NetworkPackage::PACKAGE_DATA_HASH]);
+ // Set content/hash to null
+ $packageInstance->setContent(NULL);
+ $packageInstance->setHash(NULL);
// Set the resource ...
$socketInstance->setSocketResource($socketResource);
- // ... and package data
- $socketInstance->setPackageData($packageData);
+ // ... and package instance
+ $socketInstance->setPackageDataInstance($packageInstance);
// Return the prepared instance
return $socketInstance;
//* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('%s-SOCKET: unl=%s - CALLED!', strtoupper($this->getSocketProtocol()), $unl));
// Get current package data
- $packageData = $this->getPackageData();
+ $packageInstance = $this->getPackageDataInstance();
// Debug message
- //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(strtoupper($this->getSocketProtocol()) . '-SOCKET: unl=' . $unl . ',packageData=' . print_r($packageData, true));
+ //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(strtoupper($this->getSocketProtocol()) . '-SOCKET: unl=' . $unl . ',packageInstance=' . print_r($packageInstance, true));
// So, does both match?
- $matches = ((isset($packageData[NetworkPackage::PACKAGE_DATA_RECIPIENT])) && ($packageData[NetworkPackage::PACKAGE_DATA_RECIPIENT] === $unl));
+ $matches = (($packageInstance->getRecipient() !== '') && ($packageInstance->getRecipient() === $unl));
// Trace message
//* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('%s-SOCKET: matches=%d - EXIT!', strtoupper($this->getSocketProtocol()), intval($matches)));
} // END - if
// Get package data
- $packageData = $this->getPackageData();
-
- // Is the element there?
- if (!isset($packageData[NetworkPackage::PACKAGE_DATA_RECIPIENT])) {
- // Abort here
- throw new LogicException(sprintf('packageData[%s] is not set.', NetworkPackage::PACKAGE_DATA_RECIPIENT));
- } // END - if
+ $packageInstance = $this->getPackageDataInstance();
// Trace message
- //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('%s-SOCKET: packageData[%s]=%s - EXIT!', strtoupper($this->getSocketProtocol()), NetworkPackage::PACKAGE_DATA_RECIPIENT, $packageData[NetworkPackage::PACKAGE_DATA_RECIPIENT]));
+ //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('%s-SOCKET: packageInstance.recipient=%s - EXIT!', strtoupper($this->getSocketProtocol()), $packageInstance->getRecipient()));
// Return it
- return $packageData[NetworkPackage::PACKAGE_DATA_RECIPIENT];
+ return $packageInstance->getRecipient();
}
/**
// Valid?
if ($result === TRUE) {
- // Get package data
- $packageData = $this->getPackageData();
-
// Set both
- $packageData[StorableSocket::SOCKET_ARRAY_INDEX_ADDRESS] = $peerAddress;
- $packageData[StorableSocket::SOCKET_ARRAY_INDEX_PORT] = $peerPort;
-
- // Set it back
- $this->setPackageData($packageData);
+ $this->getPackageDataInstance()->setAddress($peerAddress);
+ $this->getPackageDataInstance()->setPort($peerPort);
} // END - if
// Trace message
if (!$this->isValidSocket()) {
// Throw exception
throw new InvalidSocketException(array($this, $this->getSocketResource()), self::EXCEPTION_INVALID_SOCKET);
- } elseif (!isset($socketBuffer[NetworkPackage::RAW_INDEX_DIFF])) {
+ } elseif (!isset($socketBuffer[NetworkPackageHandler::RAW_INDEX_DIFF])) {
// Opps, should not happen
- throw new InvalidArgumentException(sprintf('socketBuffer[%s] is not set.', NetworkPackage::RAW_INDEX_DIFF));
- } elseif (!isset($socketBuffer[NetworkPackage::RAW_INDEX_ENCODED_DATA])) {
+ throw new InvalidArgumentException(sprintf('socketBuffer[%s] is not set.', NetworkPackageHandler::RAW_INDEX_DIFF));
+ } elseif (!isset($socketBuffer[NetworkPackageHandler::RAW_INDEX_ENCODED_DATA])) {
// Opps, should not happen
- throw new InvalidArgumentException(sprintf('socketBuffer[%s] is not set.', NetworkPackage::RAW_INDEX_ENCODED_DATA));
- } elseif (!isset($socketBuffer[NetworkPackage::RAW_INDEX_BUFFER_SIZE])) {
+ throw new InvalidArgumentException(sprintf('socketBuffer[%s] is not set.', NetworkPackageHandler::RAW_INDEX_ENCODED_DATA));
+ } elseif (!isset($socketBuffer[NetworkPackageHandler::RAW_INDEX_BUFFER_SIZE])) {
// Opps, should not happen
- throw new InvalidArgumentException(sprintf('socketBuffer[%s] is not set.', NetworkPackage::RAW_INDEX_BUFFER_SIZE));
- } elseif (!isset($socketBuffer[NetworkPackage::RAW_INDEX_SENT_BYTES])) {
+ throw new InvalidArgumentException(sprintf('socketBuffer[%s] is not set.', NetworkPackageHandler::RAW_INDEX_BUFFER_SIZE));
+ } elseif (!isset($socketBuffer[NetworkPackageHandler::RAW_INDEX_SENT_BYTES])) {
// Opps, should not happen
- throw new InvalidArgumentException(sprintf('socketBuffer[%s] is not set.', NetworkPackage::RAW_INDEX_SENT_BYTES));
+ throw new InvalidArgumentException(sprintf('socketBuffer[%s] is not set.', NetworkPackageHandler::RAW_INDEX_SENT_BYTES));
}
// Debug message
- /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('%s-SOCKET: Sending out %d bytes,rawBufferSize=%d,diff=%d to socketResource=%s', strtoupper($this->getSocketProtocol()), strlen($socketBuffer[NetworkPackage::RAW_INDEX_ENCODED_DATA]), $socketBuffer[NetworkPackage::RAW_INDEX_BUFFER_SIZE], $socketBuffer[NetworkPackage::RAW_INDEX_DIFF], $this->getSocketResource()));
+ /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('%s-SOCKET: Sending out %d bytes,rawBufferSize=%d,diff=%d to socketResource=%s', strtoupper($this->getSocketProtocol()), strlen($socketBuffer[NetworkPackageHandler::RAW_INDEX_ENCODED_DATA]), $socketBuffer[NetworkPackageHandler::RAW_INDEX_BUFFER_SIZE], $socketBuffer[NetworkPackageHandler::RAW_INDEX_DIFF], $this->getSocketResource()));
// Is some data still pending or sent all out?
- if ($socketBuffer[NetworkPackage::RAW_INDEX_DIFF] >= 0) {
+ if ($socketBuffer[NetworkPackageHandler::RAW_INDEX_DIFF] >= 0) {
// Debug message
- /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('%s-SOCKET: MD5=%s', strtoupper($this->getSocketProtocol()), md5(substr($socketBuffer[NetworkPackage::RAW_INDEX_ENCODED_DATA], 0, ($socketBuffer[NetworkPackage::RAW_INDEX_BUFFER_SIZE] - $socketBuffer[NetworkPackage::RAW_INDEX_DIFF])))));
+ /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('%s-SOCKET: MD5=%s', strtoupper($this->getSocketProtocol()), md5(substr($socketBuffer[NetworkPackageHandler::RAW_INDEX_ENCODED_DATA], 0, ($socketBuffer[NetworkPackageHandler::RAW_INDEX_BUFFER_SIZE] - $socketBuffer[NetworkPackageHandler::RAW_INDEX_DIFF])))));
// Send all out (encodedData is smaller than or equal buffer size)
- $sentBytes = socket_write($this->getSocketResource(), $socketBuffer[NetworkPackage::RAW_INDEX_ENCODED_DATA], ($socketBuffer[NetworkPackage::RAW_INDEX_BUFFER_SIZE] - $socketBuffer[NetworkPackage::RAW_INDEX_DIFF]));
+ $sentBytes = socket_write($this->getSocketResource(), $socketBuffer[NetworkPackageHandler::RAW_INDEX_ENCODED_DATA], ($socketBuffer[NetworkPackageHandler::RAW_INDEX_BUFFER_SIZE] - $socketBuffer[NetworkPackageHandler::RAW_INDEX_DIFF]));
} else {
// Debug message
- /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('%s-SOCKET: MD5=%s', strtoupper($this->getSocketProtocol()), md5(substr($socketBuffer[NetworkPackage::RAW_INDEX_ENCODED_DATA], 0, $socketBuffer[NetworkPackage::RAW_INDEX_BUFFER_SIZE]))));
+ /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('%s-SOCKET: MD5=%s', strtoupper($this->getSocketProtocol()), md5(substr($socketBuffer[NetworkPackageHandler::RAW_INDEX_ENCODED_DATA], 0, $socketBuffer[NetworkPackageHandler::RAW_INDEX_BUFFER_SIZE]))));
// Send buffer size out
- $sentBytes = socket_write($this->getSocketResource(), $socketBuffer[NetworkPackage::RAW_INDEX_ENCODED_DATA], $socketBuffer[NetworkPackage::RAW_INDEX_BUFFER_SIZE]);
+ $sentBytes = socket_write($this->getSocketResource(), $socketBuffer[NetworkPackageHandler::RAW_INDEX_ENCODED_DATA], $socketBuffer[NetworkPackageHandler::RAW_INDEX_BUFFER_SIZE]);
}
// Check if the operation was okay
// Failed delivery!
return FALSE;
- } elseif (($sentBytes === 0) && (strlen($socketBuffer[NetworkPackage::RAW_INDEX_ENCODED_DATA]) > 0)) {
+ } elseif (($sentBytes === 0) && (strlen($socketBuffer[NetworkPackageHandler::RAW_INDEX_ENCODED_DATA]) > 0)) {
// Trace message
/* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('%s-SOCKET: All sent, returning TRUE ... - EXIT!', strtoupper($this->getSocketProtocol())));
return TRUE;
} else {
// The difference between sent bytes and length of raw data should not go below zero
- assert((strlen($socketBuffer[NetworkPackage::RAW_INDEX_ENCODED_DATA]) - $sentBytes) >= 0);
+ assert((strlen($socketBuffer[NetworkPackageHandler::RAW_INDEX_ENCODED_DATA]) - $sentBytes) >= 0);
// Add total sent bytes
- $socketBuffer[NetworkPackage::RAW_INDEX_SENT_BYTES] += $sentBytes;
+ $socketBuffer[NetworkPackageHandler::RAW_INDEX_SENT_BYTES] += $sentBytes;
// Debug message
- /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('%s-SOCKET: Sent out %d of %d bytes ...', strtoupper($this->getSocketProtocol()), $sentBytes, strlen($socketBuffer[NetworkPackage::RAW_INDEX_ENCODED_DATA])));
+ /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('%s-SOCKET: Sent out %d of %d bytes ...', strtoupper($this->getSocketProtocol()), $sentBytes, strlen($socketBuffer[NetworkPackageHandler::RAW_INDEX_ENCODED_DATA])));
// Cut out the last unsent bytes
- $socketBuffer[NetworkPackage::RAW_INDEX_ENCODED_DATA] = substr($socketBuffer[NetworkPackage::RAW_INDEX_ENCODED_DATA], $sentBytes);
+ $socketBuffer[NetworkPackageHandler::RAW_INDEX_ENCODED_DATA] = substr($socketBuffer[NetworkPackageHandler::RAW_INDEX_ENCODED_DATA], $sentBytes);
// Calculate difference again
- $socketBuffer[NetworkPackage::RAW_INDEX_DIFF] = $socketBuffer[NetworkPackage::RAW_INDEX_BUFFER_SIZE] - strlen($socketBuffer[NetworkPackage::RAW_INDEX_ENCODED_DATA]);
+ $socketBuffer[NetworkPackageHandler::RAW_INDEX_DIFF] = $socketBuffer[NetworkPackageHandler::RAW_INDEX_BUFFER_SIZE] - strlen($socketBuffer[NetworkPackageHandler::RAW_INDEX_ENCODED_DATA]);
}
// Trace message
// Import application-specific stuff
use Org\Shipsimu\Hub\Database\Frontend\BaseHubDatabaseWrapper;
use Org\Shipsimu\Hub\Factory\Node\NodeObjectFactory;
-use Org\Shipsimu\Hub\Network\Package\NetworkPackage;
+use Org\Shipsimu\Hub\Handler\Package\NetworkPackageHandler;
+use Org\Shipsimu\Hub\Network\Package\DeliverablePackage;
use Org\Shipsimu\Hub\Node\BaseHubNode;
// Import framework stuff
/**
* Find recipients for given package data and exclude the sender
*
- * @param $packageData An array of valid package data
+ * @param $packageData An instance of a DeliverablePackage class
* @return $recipients An indexed array with DHT recipients
*/
- public function getResultFromExcludedSender (array $packageData) {
+ public function getResultFromExcludedSender (DeliverablePackage $packageInstance) {
// Debug message
//* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('DHT-WRAPPER: CALLED!');
- // Assert on required array field
- assert(isset($packageData[NetworkPackage::PACKAGE_DATA_SENDER_ADDRESS]));
-
// Get max recipients
$maxRecipients = $this->getConfigInstance()->getConfigEntry('max_dht_recipients');
$searchInstance = ObjectFactory::createObjectByConfiguredName('search_criteria_class');
// Then exclude 'sender' field as the sender is the current (*this*) node
- $searchInstance->addExcludeCriteria(NodeDistributedHashTableDatabaseWrapper::DB_COLUMN_SESSION_ID, $packageData[NetworkPackage::PACKAGE_DATA_SENDER_ADDRESS]);
+ $searchInstance->addExcludeCriteria(NodeDistributedHashTableDatabaseWrapper::DB_COLUMN_SESSION_ID, $packageInstance->getSenderAddress());
// Set limit to maximum DHT recipients
$searchInstance->setLimit($maxRecipients);
// Import application-specific sutff
use Org\Shipsimu\Hub\Container\Socket\StorableSocket;
use Org\Shipsimu\Hub\Database\Frontend\BaseHubDatabaseWrapper;
+use Org\Shipsimu\Hub\Handler\Package\NetworkPackageHandler;
use Org\Shipsimu\Hub\Helper\Connection\ConnectionHelper;
-use Org\Shipsimu\Hub\Network\Package\NetworkPackage;
+use Org\Shipsimu\Hub\Network\Package\DeliverablePackage;
use Org\Shipsimu\Hub\LookupTable\Lookupable;
use Org\Shipsimu\Hub\State\Peer\Lookup\LookupablePeerState;
use Org\Shipsimu\Hub\State\Peer\PeerStateable;
* @param $packageData Valid raw package data array
* @return $searchInstance An instance of a LocalSearchCriteria class
*/
- private function getSenderSearchInstanceFromPackageData (array $packageData) {
+ private function getSenderSearchInstanceFromPackageInstance (DeliverablePackage $packageInstance) {
// Get the instance
- //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('PEER-STATE-DATABASE-WRAPPER: Searching for sender ' . $packageData[NetworkPackage::PACKAGE_DATA_SENDER_ADDRESS]);
+ //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('PEER-STATE-DATABASE-WRAPPER: Searching for sender ' . $packageInstance->getSenderAddress());
$searchInstance = ObjectFactory::createObjectByConfiguredName('search_criteria_class');
// Add 'sender' as the peer's IP address
- $searchInstance->addCriteria(self::DB_COLUMN_PEER_SESSION_ID, $packageData[NetworkPackage::PACKAGE_DATA_SENDER_ADDRESS]);
+ $searchInstance->addCriteria(self::DB_COLUMN_PEER_SESSION_ID, $packageInstance->getSenderAddress());
$searchInstance->setLimit(1);
// Return the instance
/**
* Checks whether given 'sender' is a new peer
*
- * @param $packageData Raw package data
+ * @param $packageData An instance of a DeliverablePackage class
* @param $dataSetInstance An optional instance of a StoreableCriteria class
* @return $isNewPeer Whether 'sender' is a new peer to this peer
*/
- public function isSenderNewPeer (array $packageData, StoreableCriteria $dataSetInstance = NULL) {
+ public function isSenderNewPeer (DeliverablePackage $packageInstance, StoreableCriteria $dataSetInstance = NULL) {
// Debug message
//* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('PEER-STATE-DATABASE-WRAPPER: packageData()=' . count($packageData) . ' - CALLED!');
- // Is the package valid?
- if (!isset($packageData[NetworkPackage::PACKAGE_DATA_SENDER_ADDRESS])) {
- // Invalid package found, please report this
- $this->debugBackTrace(': packageData=' . print_r($packageData, TRUE));
- } // END - if
-
// Get a search criteria instance from package data
- $searchInstance = $this->getSenderSearchInstanceFromPackageData($packageData);
+ $searchInstance = $this->getSenderSearchInstanceFromPackageInstance($packageData);
// Is the dataset instance set?
if ($dataSetInstance instanceof StoreableCriteria) {
/**
* Registers a new peer with given package data. We use the session id from it.
*
- * @param $packageData Raw package data
+ * @param $packageData An instance of a DeliverablePackage class
* @param $socketResource An instance of a StorableSocket class
* @return void
* @throws PeerAlreadyRegisteredException If a peer is already registered
*/
- public function registerPeerByPackageData (array $packageData, StorableSocket $socketInstance) {
+ public function registerPeerByPackageData (DeliverablePackage $packageInstance, StorableSocket $socketInstance) {
// Make sure only new peers can be registered with package data
if (!$this->isSenderNewPeer($packageData)) {
// Throw an exception because this should normally not happen
$dataSetInstance->setUniqueKey(self::DB_COLUMN_PEER_SESSION_ID);
// Add session id
- $dataSetInstance->addCriteria(self::DB_COLUMN_PEER_SESSION_ID, $packageData[NetworkPackage::PACKAGE_DATA_SENDER_ADDRESS]);
+ $dataSetInstance->addCriteria(self::DB_COLUMN_PEER_SESSION_ID, $packageInstance->getSenderAddress());
// Init peer address/port
$peerAddress = '0.0.0.0';
$this->queryInsertDataSet($dataSetInstance, array(self::DB_COLUMN_PEER_SESSION_ID => TRUE));
// Debug message
- //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('PEER-STATE-DATABASE-WRAPPER: Peer ' . $packageData[NetworkPackage::PACKAGE_DATA_SENDER_ADDRESS] . ' has been registered.');
+ //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('PEER-STATE-DATABASE-WRAPPER: Peer ' . $packageInstance->getSenderAddress() . ' has been registered.');
}
/**
- * Registers the given peer state and raw package data
+ * Registers the given peer state and An instance of a DeliverablePackage class
*
* @param $stateInstance A PeerStateable class instance
- * @param $packageData Valid package data array
+ * @param $packageData An instance of a DeliverablePackage class
* @return void
* @throws PeerAlreadyRegisteredException If a peer is already registered
* @todo Unfinished area
*/
- public function registerPeerState (PeerStateable $stateInstance, array $packageData) {
+ public function registerPeerState (PeerStateable $stateInstance, DeliverablePackage $packageInstance) {
// Generate a dataset instance
$dataSetInstance = ObjectFactory::createObjectByConfiguredName('dataset_criteria_class', array(self::DB_TABLE_PEER_LOOKUP));
$dataSetInstance->setUniqueKey(self::DB_COLUMN_PEER_SESSION_ID);
// Add session id
- $dataSetInstance->addCriteria(self::DB_COLUMN_PEER_SESSION_ID, $packageData[NetworkPackage::PACKAGE_DATA_SENDER_ADDRESS]);
+ $dataSetInstance->addCriteria(self::DB_COLUMN_PEER_SESSION_ID, $packageInstance->getSenderAddress());
$dataSetInstance->addCriteria(self::DB_COLUMN_PEER_STATE , $stateInstance->getStateName());
// Try to resolve sender's session id
- $senderData = explode(':', HubTools::resolveSessionId($packageData[NetworkPackage::PACKAGE_DATA_SENDER_ADDRESS]));
+ $senderData = explode(':', HubTools::resolveSessionId($packageInstance->getSenderAddress()));
// Just make sure that 'invalid:invalid' is not being processed
assert(($senderData[0] != 'invalid') && ($senderData[1] != 'invalid') && ($senderData[2] != 'invalid'));
}
// Debug message
- //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('PEER-STATE-DATABASE-WRAPPER: Peer ' . $packageData[NetworkPackage::PACKAGE_DATA_SENDER_ADDRESS] . ' has been registered/updated with state ' . $stateInstance->getStateName());
+ //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('PEER-STATE-DATABASE-WRAPPER: Peer ' . $packageInstance->getSenderAddress() . ' has been registered/updated with state ' . $stateInstance->getStateName());
}
/**
* in database compared with the one from $helperInstance.
*
* @param $helperInstance An instance of a ConnectionHelper class
- * @param $packageData Valid package data array
+ * @param $packageData An instance of a DeliverablePackage class
* @return $isSamePeerState Whether the peer's state is the same
*/
- public function isSamePeerState (ConnectionHelper $helperInstance, array $packageData) {
+ public function isSamePeerState (ConnectionHelper $helperInstance, DeliverablePackage $packageInstance) {
// Debug message
//* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('PEER-STATE-DATABASE-WRAPPER: State ' . $helperInstance->getPrintableState() . ' needs to be checked it has changed ...');
// Now get the search instance from given package data
- $searchInstance = $this->getSenderSearchInstanceFromPackageData($packageData);
+ $searchInstance = $this->getSenderSearchInstanceFromPackageInstance($packageData);
// With this search instance query the database for the peer and get a result instance
$resultInstance = $this->doSelectByCriteria($searchInstance);
use Org\Shipsimu\Hub\Factory\Network\NetworkPackageFactory;
use Org\Shipsimu\Hub\Handler\Network\RawData\Chunks\ChunkHandler;
use Org\Shipsimu\Hub\Handler\Network\RawData\Chunks\HandleableChunks;
-use Org\Shipsimu\Hub\Network\Package\NetworkPackage;
+use Org\Shipsimu\Hub\Handler\Package\NetworkPackageHandler;
// Import framework stuff
use Org\Mxchange\CoreFramework\Registry\Registerable;
$decoderInstance->setHandlerInstance($handlerInstance);
// Get a singleton network package instance
- $packageInstance = NetworkPackageFactory::createNetworkPackageInstance();
+ $packageInstance = NetworkPackageHandlerFactory::createNetworkPackageHandlerInstance();
// And set it in this decoder
- $decoderInstance->setPackageInstance($packageInstance);
+ $decoderInstance->setPackageHandlerInstance($packageInstance);
// Return the prepared instance
return $decoderInstance;
// Debug message
//* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('PACKAGE-DECODER: Got ' . strlen($rawPackageContent) . ' bytes from stack ' . ChunkHandler::STACKER_NAME_ASSEMBLED_RAW_DATA . ', decoding it ...');
- // "Decode" the raw package content by using the NetworkPackage instance
- $decodedData = $this->getPackageInstance()->decodeRawContent($rawPackageContent);
-
- // Debug message
- /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('PACKAGE-DECODER: decodedData=' . print_r($decodedData, TRUE));
-
- // Some checks
- assert(
- (is_array($decodedData)) &&
- (isset($decodedData[NetworkPackage::PACKAGE_DATA_SENDER_ADDRESS])) &&
- (isset($decodedData[NetworkPackage::PACKAGE_DATA_SENDER_PORT])) &&
- (isset($decodedData[NetworkPackage::PACKAGE_DATA_RECIPIENT])) &&
- (isset($decodedData[NetworkPackage::PACKAGE_DATA_CONTENT])) &&
- (isset($decodedData[NetworkPackage::PACKAGE_DATA_STATUS]))
- );
-
- // Debug message
- //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('PACKAGE-DECODER: decodedData(' . count($decodedData) . ')=' . print_r($decodedData, TRUE));
+ // "Decode" the raw package content by using the NetworkPackageHandler instance
+ $packageInstance = $this->getPackageHandlerInstance()->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->discoverRawRecipients($decodedData);
+ $discoveryInstance->discoverRawRecipients($packageInstance);
// 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'
- //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('PACKAGE-DECODER: Pushing ' . strlen($decodedData) . ' bytes to stack ' . self::STACKER_NAME_DECODED_PACKAGE . ' ...');
- $this->getHandlerInstance()->getStackInstance()->pushNamed(self::STACKER_NAME_DECODED_PACKAGE, $decodedData);
+ //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('PACKAGE-DECODER: Pushing ' . strlen($packageInstance) . ' bytes to stack ' . self::STACKER_NAME_DECODED_PACKAGE . ' ...');
+ $this->getHandlerInstance()->getStackInstance()->pushNamed(self::STACKER_NAME_DECODED_PACKAGE, $packageInstance);
} else {
// Forward the package to the next node
- $this->getPackageInstance()->forwardRawPackage($decodedData);
+ $this->getPackageHandlerInstance()->forwardRawPackage($packageInstance);
}
}
assert($this->ifDeocedPackagesLeft());
// Get the next entry (assoziative array)
- $decodedData = $this->getHandlerInstance()->getStackInstance()->popNamed(self::STACKER_NAME_DECODED_PACKAGE);
+ $packageInstance = $this->getHandlerInstance()->getStackInstance()->popNamed(self::STACKER_NAME_DECODED_PACKAGE);
// Handle it
- //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('PACKAGE-DECODER: decodedData(' . count($decodedData) . ')=' . print_r($decodedData, TRUE));
- $this->getPackageInstance()->handleRawData($decodedData);
+ //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('PACKAGE-DECODER: decodedData(' . count($packageInstance) . ')=' . print_r($packageInstance, TRUE));
+ $this->getPackageHandlerInstance()->handleRawData($packageInstance);
}
}
use Org\Shipsimu\Hub\Dht\BaseDht;
use Org\Shipsimu\Hub\Dht\Distributable;
use Org\Shipsimu\Hub\Generic\BaseHubSystem;
+use Org\Shipsimu\Hub\Network\Package\DeliverablePackage;
// Import framework stuff
use Org\Mxchange\CoreFramework\Factory\Database\Wrapper\DatabaseWrapperFactory;
/**
* Find recipients for given package data
*
- * @param $packageData An array of valid package data
+ * @param $packageData An instance of a DeliverablePackage class
* @return $recipients An indexed array with DHT recipients
*/
- public function findRecipientsByPackageData (array $packageData) {
+ public function findRecipientsByPackageData (DeliverablePackage $packageInstance) {
// Query get a result instance back from DHT database wrapper.
$resultInstance = $this->getWrapperInstance()->getResultFromExcludedSender($packageData);
// Import application-specific stuff
use Org\Shipsimu\Hub\Discovery\Node\BaseNodeDiscovery;
use Org\Shipsimu\Hub\Factory\Tag\Package\PackageTagsFactory;
-use Org\Shipsimu\Hub\Network\Package\NetworkPackage;
+use Org\Shipsimu\Hub\Handler\Package\NetworkPackageHandler;
+use Org\Shipsimu\Hub\Network\Package\DeliverablePackage;
// Import framework stuff
use Org\Mxchange\CoreFramework\Registry\Registerable;
* @param $packageData Valid package data
* @return $protocolInstance An instance of a HandleableProtocol class
*/
- public static final function determineProtocolByPackageData (array $packageData) {
+ public static final function determineProtocolByPackageData (DeliverablePackage $packageInstance) {
// First we need a tags instance
$tagsInstance = PackageTagsFactory::createPackageTagsInstance();
* and if so we can re-use it. If there is no socket registered, we try
* to make a new connection to the given Universal Node Locator.
*/
- $protocolInstance = $tagsInstance->chooseProtocolFromPackageData($packageData);
+ $protocolInstance = $tagsInstance->chooseProtocolFromPackageInstance($packageData);
// Return it
return $protocolInstance;
* "Discovers" the protocol type from given raw package data. This is done
* by looking at the 'recipient' field and extract the first part from it.
*
- * @param $packageData Raw package data
+ * @param $packageData An instance of a DeliverablePackage class
* @return $protocolType Type of protocol, e.g. 'tcp' for TCP/IPv4 connections
*/
- public static final function discoverProtocolByPackageData (array $packageData) {
+ public static final function discoverProtocolByPackageData (DeliverablePackage $packageInstance) {
//* DEBUG: */ die(__METHOD__ . ':packageData=' . print_r($packageData, TRUE));
/*
* "Explode" the 'recipient' array element into a new one, giving at
* least two entries: protocol://address
*/
- $recipient = explode(':', $packageData[NetworkPackage::PACKAGE_DATA_RECIPIENT]);
+ $recipient = explode(':', $packageInstance->getRecipient());
// At least 2 entries must be found
assert(count($recipient) >= 2);
// Import application-specific stuff
use Org\Shipsimu\Hub\Discovery\Recipient\BaseRecipientDiscovery;
use Org\Shipsimu\Hub\Factory\Dht\DhtObjectFactory;
+use Org\Shipsimu\Hub\Network\Package\DeliverablePackage;
// Import framework stuff
use Org\Mxchange\CoreFramework\Registry\Registerable;
/**
* Resolves one or more recipients for a DHT transfer by given package data.
*
- * @param $packageData Valid package data array
+ * @param $packageData An instance of a DeliverablePackage class
* @return $recipients An indexed array with DHT recipients
*/
- public function resolveRecipientsByPackageData (array $packageData) {
+ public function resolveRecipientsByPackageData (DeliverablePackage $packageInstance) {
// Use facade to get recipients back
$recipients = DhtObjectFactory::createDhtInstance('node')->findRecipientsByPackageData($packageData);
use Org\Shipsimu\Hub\Discovery\Recipient\BaseRecipientDiscovery;
use Org\Shipsimu\Hub\Discovery\Recipient\Node\DiscoverableNodeRecipient;
use Org\Shipsimu\Hub\Factory\Handler\Protocol\ProtocolHandlerFactory;
+use Org\Shipsimu\Hub\Handler\Package\NetworkPackageHandler;
use Org\Shipsimu\Hub\Locator\Node\Tools\NodeLocatorUtils;
-use Org\Shipsimu\Hub\Network\Package\NetworkPackage;
+use Org\Shipsimu\Hub\Network\Package\DeliverablePackage;
use Org\Shipsimu\Hub\Node\Data\InvalidSessionIdException;
use Org\Shipsimu\Hub\Tools\HubTools;
/**
* Tries to discover all recipients for given package data
*
- * @param $packageData Raw package data array
+ * @param $packageData An instance of a DeliverablePackage class array
* @return void
*/
- public function discoverRecipients (array $packageData) {
- // This must be available
- //* DEBUG: */ print $this->__toString() . ': packageData=' . print_r($packageData, TRUE);
- assert(isset($packageData[NetworkPackage::PACKAGE_DATA_RECIPIENT]));
-
+ public function discoverRecipients (DeliverablePackage $packageInstance) {
// Init instance
$recipientInstance = NULL;
* recipient must be direct recipient then, otherwise a "virtual"
* recipient.
*/
- if (NodeLocatorUtils::isValidUniversalNodeLocator($packageData[NetworkPackage::PACKAGE_DATA_RECIPIENT])) {
+ if (NodeLocatorUtils::isValidUniversalNodeLocator($packageInstance->getRecipient())) {
// Get instance (should not break)
$recipientInstance = ObjectFactory::createObjectByConfiguredName('direct_recipient_class');
} else {
// Try to find the right class
- $recipientInstance = ObjectFactory::createObjectByConfiguredName(strtolower($packageData[NetworkPackage::PACKAGE_DATA_RECIPIENT]) . '_recipient_class');
+ $recipientInstance = ObjectFactory::createObjectByConfiguredName(strtolower($packageInstance->getRecipient()) . '_recipient_class');
}
// Try to solve it
- $recipientInstance->resolveRecipient($packageData[NetworkPackage::PACKAGE_DATA_RECIPIENT], $this->getListInstance(), $packageData);
+ $recipientInstance->resolveRecipient($packageInstance->getRecipient(), $this->getListInstance(), $packageData);
} catch (FrameworkException $e) {
// Could not find class, what ever failed
$this->debugInstance(sprintf('[%s:%d]: Exception: %s,message=%s', __METHOD__, __LINE__, $e->__toString(), $e->getMessage()));
/**
* Tries to discover all recipients by given decoded package data.
*
- * @param $decodedData Raw raw package data array
+ * @param $packageInstance An instance of a DeliverablePackage class
* @return void
* @todo Add some validation of recipient field, e.g. an Universal Node Locator is found
* @todo Enrich both messages with recipient data
*/
- public function discoverRawRecipients (array $decodedData) {
- // This must be available
- assert(isset($decodedData[NetworkPackage::PACKAGE_DATA_RECIPIENT]));
-
+ public function discoverRawRecipients (DeliverablePackage $packageInstance) {
// First clear all recipients
$this->clearRecipients();
// Get a protocol handler back from decoded data
- $handlerInstance = ProtocolHandlerFactory::createProtocolHandlerFromPackageData($decodedData);
+ $handlerInstance = ProtocolHandlerFactory::createProtocolHandlerFromPackageInstance($packageInstance);
// Is the 'recipient' field same as this peer's IP?
- if ($handlerInstance->isOwnAddress($decodedData[NetworkPackage::PACKAGE_DATA_RECIPIENT])) {
+ if ($handlerInstance->isOwnAddress($packageInstance->getRecipient())) {
/*
* Is same as own external address + TCP/UDP listen port or
* internal address, don't do anything here so other classes found
*/
// Debug output (may flood)
- /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('RECIPIENT-DISCOVERY: Recipient ' . $decodedData[NetworkPackage::PACKAGE_DATA_RECIPIENT] . ' matches own ip (external=' . HubTools::determineOwnExternalAddress() . ' or internal=' . HubTools::determineOwnInternalAddress() . ')');
+ /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('RECIPIENT-DISCOVERY: Recipient ' . $packageInstance->getRecipient() . ' matches own ip (external=' . HubTools::determineOwnExternalAddress() . ' or internal=' . HubTools::determineOwnInternalAddress() . ')');
} else {
// Debug output (may flood)
- /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('RECIPIENT-DISCOVERY: Recipient ' . $decodedData[NetworkPackage::PACKAGE_DATA_RECIPIENT] . ' is different than own external address (' . HubTools::determineOwnExternalAddress() . ') nor internal address (' . HubTools::determineOwnInternalAddress() . '), need to forward (not yet implemented)!');
+ /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('RECIPIENT-DISCOVERY: Recipient ' . $packageInstance->getRecipient() . ' is different than own external address (' . HubTools::determineOwnExternalAddress() . ') nor internal address (' . HubTools::determineOwnInternalAddress() . '), need to forward (not yet implemented)!');
// This package is to be delivered to someone else, so add it
- // @TODO Unfinished: $this->getListInstance()->addEntry('unl', $decodedData[NetworkPackage::PACKAGE_DATA_RECIPIENT]);
+ // @TODO Unfinished: $this->getListInstance()->addEntry('unl', $packageInstance->getRecipient());
}
}
use Org\Shipsimu\Hub\Factory\Node\NodeObjectFactory;
use Org\Shipsimu\Hub\Factory\Socket\SocketFactory;
use Org\Shipsimu\Hub\Generic\BaseHubSystem;
+use Org\Shipsimu\Hub\Handler\Package\NetworkPackageHandler;
use Org\Shipsimu\Hub\Handler\Protocol\HandleableProtocol;
use Org\Shipsimu\Hub\Listener\Listenable;
-use Org\Shipsimu\Hub\Network\Package\NetworkPackage;
+use Org\Shipsimu\Hub\Network\Package\DeliverablePackage;
use Org\Shipsimu\Hub\Resolver\State\Peer\PeerStateResolver;
// Import framework stuff
* Tries to dicover the right listener instance
*
* @param $protocolInstance An instance of a HandleableProtocol class
- * @param $packageData Raw package data
+ * @param $packageData An instance of a DeliverablePackage class
* @return $listenerInstance An instance of a Listenable instance or null
*/
- public function discoverListenerInstance (HandleableProtocol $protocolInstance, array $packageData) {
+ public function discoverListenerInstance (HandleableProtocol $protocolInstance, DeliverablePackage $packageInstance) {
// Debug message
/* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('PACKAGE-SOCKET-DISCOVERY: protocolInstance=' . $protocolInstance->__toString() . ' - CALLED!');
* Tries to discover the right socket for given package data and returns a
* matching socket resource for that protocol.
*
- * @param $packageData Raw package data array
+ * @param $packageData An instance of a DeliverablePackage class array
* @param $connectionType Type of connection, can be either 'incoming' or 'outgoing', but *NEVER* 'server'!
* @return $socketResource A valid socket resource or FALSE if an error occured
* @throws NoListGroupException If the procol group is not found in peer list
* @throws InvalidArgumentException If one of the parameters are not valid
* @throws LogicException If the discovered listener instance has no pool set
*/
- public function discoverSocket (array $packageData, $connectionType) {
+ public function discoverSocket (DeliverablePackage $packageInstance, $connectionType) {
// Debug message
/* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('PACKAGE-SOCKET-DISOVERY: packageData()=' . count($packageData) . ',connectionType=' . $connectionType . ' - CALLED!');
/* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('PACKAGE-SOCKET-DISOVERY: packageData=' . print_r($packageData, TRUE));
// Make sure all parameters are valid
- if (!isset($packageData[NetworkPackage::PACKAGE_DATA_RECIPIENT])) {
- // Abort here
- throw new InvalidArgumentException(sprintf('Array packageData(%d) does not contain field "%s".', count($packageData), NetworkPackage::PACKAGE_DATA_RECIPIENT));
- } elseif (($connectionType != StorableSocket::CONNECTION_TYPE_INCOMING) && ($connectionType != StorableSocket::CONNECTION_TYPE_OUTGOING)) {
+ if (($connectionType != StorableSocket::CONNECTION_TYPE_INCOMING) && ($connectionType != StorableSocket::CONNECTION_TYPE_OUTGOING)) {
// Abort here
throw new InvalidArgumentException(sprintf('connectionType=%s is whether "%s" nor "%s".', $connectionType, StorableSocket::CONNECTION_TYPE_INCOMING, StorableSocket::CONNECTION_TYPE_OUTGOING));
- }
+ } // END - if
// Determine protocol instance
$protocolInstance = ProtocolDiscovery::determineProtocolByPackageData($packageData);
* instance and pass over the whole package data to get the right
* socket.
*/
- $socketInstance = $listenerInstance->getPoolInstance()->getSocketFromPackageData($packageData, $connectionType);
+ $socketInstance = $listenerInstance->getPoolInstance()->getSocketFromPackageInstance($packageData, $connectionType);
// Debug message
/* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('PACKAGE-SOCKET-DISCOVERY: socketInstance[]=%s', gettype($socketInstance)));
// Try to create a new socket resource
try {
// Possibly noisy debug message
- /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('PACKAGE-SOCKET-DISCOVERY: Trying to establish a ' . strtoupper($listenerInstance->getProtocolName()) . ' connection to ' . $packageData[NetworkPackage::PACKAGE_DATA_RECIPIENT] . ' ...');
+ /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('PACKAGE-SOCKET-DISCOVERY: Trying to establish a ' . strtoupper($listenerInstance->getProtocolName()) . ' connection to ' . $packageInstance->getRecipient() . ' ...');
// Get a socket resource from our factory (if succeeded)
- $socketInstance = SocketFactory::createSocketFromPackageData($packageData, $protocolInstance);
+ $socketInstance = SocketFactory::createSocketFromPackageInstance($packageData, $protocolInstance);
} catch (SocketConnectionException $e) {
// The connection fails of being established, so log it away
self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('PACKAGE-SOCKET-DISCOVERY: Caught ' . $e->__toString() . ',message=' . $e->getMessage());
PeerStateResolver::resolveStateByPackage($helperInstance, $packageData, $socketInstance);
} catch (InvalidSocketException $e) {
// This cannot be fixed, so log it away
- self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('PACKAGE-SOCKET-DISCOVERY: Cannot discover socket resource for recipient ' . $packageData[NetworkPackage::PACKAGE_DATA_RECIPIENT] . ': ' . $e->getMessage());
+ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('PACKAGE-SOCKET-DISCOVERY: Cannot discover socket resource for recipient ' . $packageInstance->getRecipient() . ': ' . $e->getMessage());
// Make any failed attempts to 'FALSE'
$socketInstance = NULL;
--- /dev/null
+<?php
+// Own namespace
+namespace Org\Shipsimu\Hub\Factory\Handler\Network;
+
+// Import framework stuff
+use Org\Mxchange\CoreFramework\Factory\ObjectFactory;
+use Org\Mxchange\CoreFramework\Registry\GenericRegistry;
+
+/**
+ * A factory class for network packages
+ *
+ * @author Roland Haeder <webmaster@shipsimu.org>
+ * @version 0.0.0
+ * @copyright Copyright (c) 2007, 2008 Roland Haeder, 2009 - 2018 Hub Developer Team
+ * @license GNU GPL 3.0 or any newer version
+ * @link http://www.shipsimu.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 NetworkPackageHandlerFactory extends ObjectFactory {
+ /**
+ * Protected constructor
+ *
+ * @return void
+ */
+ protected function __construct () {
+ // Call parent constructor
+ parent::__construct(__CLASS__);
+ }
+
+ /**
+ * Returns a singleton network package handler instance. If an instance is
+ * found in the registry it will be returned, else a new instance is created
+ * and stored in the same registry entry.
+ *
+ * @return $handlerInstance A network package handler instance
+ */
+ public static final function createNetworkPackageHandlerInstance () {
+ // Do we have an instance in the registry?
+ if (GenericRegistry::getRegistry()->instanceExists('network_package_handler')) {
+ // Then use this instance
+ $handlerInstance = GenericRegistry::getRegistry()->getInstance('network_package_handler');
+ } else {
+ /*
+ * Prepare the compressor for our package, ZLIB should be fine but we
+ * keep it open here so you can experiment with the settings and don't
+ * need to touch this code.
+ */
+ $compressorInstance = self::createObjectByConfiguredName('raw_package_compressor_class');
+
+ // Prepare the decorator compressor (for later flawless and easy updates)
+ $compressorInstance = self::createObjectByConfiguredName('deco_package_compressor_class', array($compressorInstance));
+
+ /*
+ * Now prepare the network package for delivery so only need to do this
+ * once just before the "big announcement loop".
+ */
+ $handlerInstance = self::createObjectByConfiguredName('network_package_handler_class', array($compressorInstance));
+
+ // Set the instance in registry for further use
+ GenericRegistry::getRegistry()->addInstance('network_package_handler', $handlerInstance);
+ }
+
+ // Return the instance
+ return $handlerInstance;
+ }
+
+}
// Import application-specific stuff
use Org\Shipsimu\Hub\Discovery\Protocol\ProtocolDiscovery;
use Org\Shipsimu\Hub\Helper\HubHelper;
+use Org\Shipsimu\Hub\Network\Package\DeliverablePackage;
// Import framework stuff
use Org\Mxchange\CoreFramework\Factory\ObjectFactory;
* @param $packageData An array with raw package data
* @return $handlerInstance A protocol handler instance
*/
- public static final function createProtocolHandlerFromPackageData (array $packageData) {
+ public static final function createProtocolHandlerFromPackageInstance (DeliverablePackage $packageInstance) {
// "Discover" the protocol type
$protocolType = ProtocolDiscovery::discoverProtocolByPackageData($packageData);
*
* @return $packageInstance A network package instance
*/
- public static final function createNetworkPackageInstance () {
+ public static final function createNetworkPackageHandlerInstance () {
// Do we have an instance in the registry?
if (GenericRegistry::getRegistry()->instanceExists('network_package')) {
// Then use this instance
--- /dev/null
+Deny from all
--- /dev/null
+<?php
+// Own namespace
+namespace Org\Shipsimu\Hub\Factory\Network;
+
+// Import framework stuff
+use Org\Mxchange\CoreFramework\Factory\ObjectFactory;
+use Org\Mxchange\CoreFramework\Registry\GenericRegistry;
+
+/**
+ * A factory class for network packages
+ *
+ * @author Roland Haeder <webmaster@shipsimu.org>
+ * @version 0.0.0
+ * @copyright Copyright (c) 2007, 2008 Roland Haeder, 2009 - 2018 Hub Developer Team
+ * @license GNU GPL 3.0 or any newer version
+ * @link http://www.shipsimu.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 PackageDataFactory extends ObjectFactory {
+ /**
+ * Protected constructor
+ *
+ * @return void
+ */
+ protected function __construct () {
+ // Call parent constructor
+ parent::__construct(__CLASS__);
+ }
+
+ /**
+ * Returns a singleton DeliverablePackage instance. If an instance is found
+ * in the registry it will be returned, else a new instance is created and
+ * stored in the same registry entry.
+ *
+ * @return $packageInstance An instance of a DeliverablePackage class
+ */
+ public static final function createPackageDataInstance () {
+ // Do we have an instance in the registry?
+ if (GenericRegistry::getRegistry()->instanceExists('package_data')) {
+ // Then use this instance
+ $packageInstance = GenericRegistry::getRegistry()->getInstance('package_data');
+ } else {
+ /*
+ * Now prepare the network package for delivery so only need to do this
+ * once just before the "big announcement loop".
+ */
+ $packageInstance = self::createObjectByConfiguredName('package_data_class');
+
+ // Set the instance in registry for further use
+ GenericRegistry::getRegistry()->addInstance('package_data', $packageInstance);
+ }
+
+ // Return the instance
+ return $packageInstance;
+ }
+
+}
// Import application-specific stuff
use Org\Shipsimu\Hub\Container\Socket\StorableSocket;
+use Org\Shipsimu\Hub\Factory\Network\PackageDataFactory;
+use Org\Shipsimu\Hub\Handler\Package\NetworkPackageHandler;
use Org\Shipsimu\Hub\Handler\Protocol\HandleableProtocol;
use Org\Shipsimu\Hub\Listener\BaseListener;
use Org\Shipsimu\Hub\Listener\Listenable;
-use Org\Shipsimu\Hub\Network\Package\NetworkPackage;
+use Org\Shipsimu\Hub\Network\Package\DeliverablePackage;
use Org\Shipsimu\Hub\Pool\Poolable;
// Import framework stuff
/**
* Creates a valid socket resource from given packae data and protocol
*
- * @param $packageData Raw package data
+ * @param $packageInstance An instance of a DeliverablePackage class
* @param $protocolInstance An instance of a HandleableProtocol class
* @return $socketInstance An instance of a StorableSocket class
*/
- public static function createSocketFromPackageData (array $packageData, HandleableProtocol $protocolInstance) {
+ public static function createSocketFromPackageInstance (DeliverablePackage $packageInstance, HandleableProtocol $protocolInstance) {
// Init instance
$socketInstance = NULL;
// Construct registry key
- $registryKey = 'socket_' . $protocolInstance->getProtocolName() . '_' . $packageData[NetworkPackage::PACKAGE_DATA_RECIPIENT];
+ $registryKey = 'socket_' . $protocolInstance->getProtocolName() . '_' . $packageInstance->getRecipient();
// Debug message
//* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('SOCKET-FACTORY: Trying to find a socket with registryKey=' . $registryKey);
//* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('SOCKET-FACTORY: Going to use class ' . $className . ' for creating a socket resource ...');
// And call the static method
- $socketInstance = call_user_func($className . '::createConnectionFromPackageData', $packageData);
+ $socketInstance = call_user_func($className . '::createConnectionFromPackageInstance', $packageInstance);
// Register it with the registry
GenericRegistry::getRegistry()->addInstance($registryKey, $socketInstance);
// File name must not be empty
assert(!empty($socketFile));
- // Init package data
- $packageData = array(
- StorableSocket::SOCKET_ARRAY_INDEX_FILE => $socketFile,
- '__fake_port' => '0',
- StorableSocket::SOCKET_ARRAY_INDEX_TYPE => StorableSocket::CONNECTION_TYPE_SERVER,
- );
+ // Init package instance
+ $packageInstance = PackageDataFactory::createPackageDataInstance();
+
+ // Set file socket data
+ $packageInstance->setSocketFile($socketFile);
+ $packageInstance->setSocketType(StorableSocket::CONNECTION_TYPE_SERVER);
// Init main socket
$socketResource = socket_create(AF_UNIX, SOCK_STREAM, 0);
// Get container from it
- $socketInstance = self::createObjectByConfiguredName('socket_container_class', array($socketResource, StorableSocket::SOCKET_PROTOCOL_FILE, $packageData));
+ $socketInstance = self::createObjectByConfiguredName('socket_container_class', array($socketResource, StorableSocket::SOCKET_PROTOCOL_FILE, $packageInstance));
// Debug message
//* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('SOCKET-FACTORY: socketInstance[]=%s', gettype($socketInstance)));
// Check if there was an error else
if ($socketInstance->getLastSocketErrorCode() > 0) {
// Handle this socket error with a faked recipientData array
- $socketInstance->handleSocketError(__METHOD__, __LINE__, array_values($packageData));
+ $socketInstance->handleSocketError(__METHOD__, __LINE__, $packageInstance->getAllValuesAsArray());
} // END - if
// Is the file there?
- if ((FrameworkBootstrap::isReachableFilePath($packageData[StorableSocket::SOCKET_ARRAY_INDEX_FILE])) && (file_exists($packageData[StorableSocket::SOCKET_ARRAY_INDEX_FILE]))) {
+ if ((FrameworkBootstrap::isReachableFilePath($packageInstance->getSocketFile())) && (file_exists($packageInstance->getSocketFile()))) {
// Old socket found
- self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('SOCKET-FACTORY: WARNING: Old socket at ' . $packageData[StorableSocket::SOCKET_ARRAY_INDEX_FILE] . ' found. Will not start.');
+ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('SOCKET-FACTORY: WARNING: Old socket at ' . $packageInstance->getSocketFile() . ' found. Will not start.');
// Shutdown this socket
$socketInstance->shutdownSocket();
} // END - if
// Debug message
- self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('SOCKET-FACTORY: Binding to ' . $packageData[StorableSocket::SOCKET_ARRAY_INDEX_FILE] . ' ...');
+ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('SOCKET-FACTORY: Binding to ' . $packageInstance->getSocketFile() . ' ...');
// Try to bind to it
- if (!$socketInstance->bindSocketTo($packageData[StorableSocket::SOCKET_ARRAY_INDEX_FILE])) {
+ if (!$socketInstance->bindSocketTo($packageInstance->getSocketFile())) {
// Handle error here
$socketInstance->handleSocketError(__METHOD__, __LINE__, array_values($packageData));
} // END - if
* Creates a socket instance from given package data. The socket then
* can be used to make outgoing TCP/IPv4/6 connections.
*
- * @param $packageData Valid package data
+ * @param $packageInstance An instance of a DeliverablePackge class
* @return $socketInstance An instance of a StorableSocket class
* @throws SocketCreationException If the socket cannot be created
* @todo Rewrite this to also handle IPv6 addresses and sockets
*/
- public static final function createTcpOutgoingSocketFromPackageData (array $packageData) {
+ public static final function createTcpOutgoingSocketFromPackageInstance (DeliverablePackage $packageInstance) {
// Trace message
- //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('SOCKET-FACTORY: packageData=' . print_r($packageData, TRUE) . ' - CALLED!');
+ //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('SOCKET-FACTORY: packageInstance=%s - CALLED!', $packageInstance->__toString()));
// Create a socket instance
$socketResource = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
// Trace message
//* NOISY-DEBUG */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('SOCKET-FACTORY: listenerInstance=%s - CALLED!', $listenerInstance->__toString()));
- // Create a streaming socket, of type TCP/IP
+ // Create a streaming socket, of type UDP
$socketResource = socket_create(AF_INET, SOCK_DGRAM, SOL_UDP);
// Init fake package data with address/port from listener
// Import application-specific stuff
use Org\Shipsimu\Hub\Container\Socket\StorableSocket;
use Org\Shipsimu\Hub\Helper\Connection\ConnectionHelper;
+use Org\Shipsimu\Hub\Network\Package\DeliverablePackage;
// Import framework stuff
use Org\Mxchange\CoreFramework\Factory\ObjectFactory;
* from current state.
*
* @param $helperInstance An instance of a ConnectionHelper class
- * @param $packageData Raw package data
+ * @param $packageData An instance of a DeliverablePackage class
* @param $socketInstance A valid socket resource
* @param $errorCode The last error code
* @return $stateInstance A Stateable class instance
*/
- public static final function createPeerStateInstanceBySocketStatusCode (ConnectionHelper $helperInstance, array $packageData, StorableSocket $socketInstance, $errorCode) {
+ public static final function createPeerStateInstanceBySocketStatusCode (ConnectionHelper $helperInstance, DeliverablePackage $packageInstance, StorableSocket $socketInstance, $errorCode) {
// Init state instance, this is better coding practice
$stateInstance = NULL;
namespace Org\Shipsimu\Hub\Filter;
// Import application-specific stuff
-use Org\Shipsimu\Hub\Network\Package\NetworkPackage;
+use Org\Shipsimu\Hub\Handler\Package\NetworkPackageHandler;
use Org\Shipsimu\Hub\Network\Receive\Receivable;
// Import framework stuff
*/
protected function genericProcessMessage ($messageType, array $messageData, Receivable $packageInstance) {
// Make sure the wanted element is there
- assert(isset($messageData[NetworkPackage::PACKAGE_CONTENT_MESSAGE]));
- assert(isset($messageData[NetworkPackage::PACKAGE_CONTENT_SENDER]));
- assert(isset($messageData[NetworkPackage::PACKAGE_CONTENT_HASH]));
- assert(isset($messageData[NetworkPackage::PACKAGE_CONTENT_TAGS]));
+ assert(isset($messageData[NetworkPackageHandler::PACKAGE_CONTENT_MESSAGE]));
+ assert(isset($messageData[NetworkPackageHandler::PACKAGE_CONTENT_SENDER]));
+ assert(isset($messageData[NetworkPackageHandler::PACKAGE_CONTENT_HASH]));
+ assert(isset($messageData[NetworkPackageHandler::PACKAGE_CONTENT_TAGS]));
// Get a template instance from the factory
$templateInstance = XmlTemplateEngineFactory::createXmlTemplateEngineInstance('node_' . $messageType . '_template_class');
// Get message content
- $messageContent = $messageData[NetworkPackage::PACKAGE_CONTENT_MESSAGE];
+ $messageContent = $messageData[NetworkPackageHandler::PACKAGE_CONTENT_MESSAGE];
// And render the XML content (aka message)
$templateInstance->renderXmlContent($messageContent);
// Construct an array for pushing it on next stack
$messageArray = array(
// Message data itself
- NetworkPackage::MESSAGE_ARRAY_DATA => $this->dataXmlNodes,
+ NetworkPackageHandler::MESSAGE_ARRAY_DATA => $this->dataXmlNodes,
// Message type (which is $messageType)
- NetworkPackage::MESSAGE_ARRAY_TYPE => $messageType,
+ NetworkPackageHandler::MESSAGE_ARRAY_TYPE => $messageType,
// Message sender
- NetworkPackage::MESSAGE_ARRAY_SENDER => $messageData[NetworkPackage::PACKAGE_CONTENT_SENDER],
+ NetworkPackageHandler::MESSAGE_ARRAY_SENDER => $messageData[NetworkPackageHandler::PACKAGE_CONTENT_SENDER],
// Package hash
- NetworkPackage::MESSAGE_ARRAY_HASH => $messageData[NetworkPackage::PACKAGE_CONTENT_HASH],
+ NetworkPackageHandler::MESSAGE_ARRAY_HASH => $messageData[NetworkPackageHandler::PACKAGE_CONTENT_HASH],
// Package tags
- NetworkPackage::MESSAGE_ARRAY_TAGS => $messageData[NetworkPackage::PACKAGE_CONTENT_TAGS],
+ NetworkPackageHandler::MESSAGE_ARRAY_TAGS => $messageData[NetworkPackageHandler::PACKAGE_CONTENT_TAGS],
);
// Push the processed message back on stack
- $packageInstance->getStackInstance()->pushNamed(NetworkPackage::STACKER_NAME_PROCESSED_MESSAGE, $messageArray);
+ $packageInstance->getStackInstance()->pushNamed(NetworkPackageHandler::STACKER_NAME_PROCESSED_MESSAGE, $messageArray);
}
}
private $eopChunk = array();
/**
- * Raw package data
+ * An instance of raw package data
*/
private $rawPackageData = '';
--- /dev/null
+Deny from all
--- /dev/null
+<?php
+// Own namespace
+namespace Org\Shipsimu\Hub\Handler\Package;
+
+// Import application-specific stuff
+use Org\Shipsimu\Hub\Container\Socket\StorableSocket;
+use Org\Shipsimu\Hub\Database\Frontend\Node\Dht\NodeDistributedHashTableDatabaseWrapper;
+use Org\Shipsimu\Hub\Factory\Assembler\Package\PackageAssemblerFactory;
+use Org\Shipsimu\Hub\Factory\Dht\DhtObjectFactory;
+use Org\Shipsimu\Hub\Factory\Discovery\Package\PackageDiscoveryFactory;
+use Org\Shipsimu\Hub\Factory\Discovery\Socket\SocketDiscoveryFactory;
+use Org\Shipsimu\Hub\Factory\FilterChain\Package\PackageFilterChainFactory;
+use Org\Shipsimu\Hub\Factory\Handler\Message\MessageTypeHandlerFactory;
+use Org\Shipsimu\Hub\Factory\Information\Connection\ConnectionInfoFactory;
+use Org\Shipsimu\Hub\Factory\Node\NodeObjectFactory;
+use Org\Shipsimu\Hub\Handler\BaseHubHandler;
+use Org\Shipsimu\Hub\Handler\Network\RawData\HandleableRawData;
+use Org\Shipsimu\Hub\Helper\Connection\ConnectionHelper;
+use Org\Shipsimu\Hub\Helper\HubHelper;
+use Org\Shipsimu\Hub\Information\ShareableInfo;
+use Org\Shipsimu\Hub\Network\Deliver\Deliverable;
+use Org\Shipsimu\Hub\Network\Networkable;
+use Org\Shipsimu\Hub\Network\Package\DeliverablePackage;
+use Org\Shipsimu\Hub\Network\Package\Fragment\PackageFragmenter;
+use Org\Shipsimu\Hub\Network\Receive\Receivable;
+use Org\Shipsimu\Hub\Node\Generic\InvalidPrivateKeyHashException;
+use Org\Shipsimu\Hub\Tag\Tagable;
+use Org\Shipsimu\Hub\Tools\HubTools;
+
+// Import framework stuff
+use Org\Mxchange\CoreFramework\Compressor\Compressor;
+use Org\Mxchange\CoreFramework\Factory\ObjectFactory;
+use Org\Mxchange\CoreFramework\Factory\Registry\Socket\SocketRegistryFactory;
+use Org\Mxchange\CoreFramework\Feature\FrameworkFeature;
+use Org\Mxchange\CoreFramework\Registry\GenericRegistry;
+use Org\Mxchange\CoreFramework\Registry\Registerable;
+use Org\Mxchange\CoreFramework\Socket\InvalidSocketException;
+use Org\Mxchange\CoreFramework\Visitor\Visitable;
+use Org\Mxchange\CoreFramework\Visitor\Visitor;
+
+// Import SPL stuff
+use \Iterator;
+
+/**
+ * A NetworkPackageHandler class. This class implements Deliverable and Receivable
+ * because all network packages should be deliverable to other nodes and
+ * receivable from other nodes. It further provides methods for reading raw
+ * content from template engines and feeding it to the stacker for undeclared
+ * packages.
+ *
+ * The factory method requires you to provide a compressor class (which must
+ * implement the Compressor interface). If you don't want any compression (not
+ * adviceable due to increased network load), please use the NullCompressor
+ * class and encode it with BASE64 for a more error-free transfer over the
+ * network.
+ *
+ * For performance reasons, this class should only be instanciated once and then
+ * used as a "pipe-through" class.
+ *
+ * @author Roland Haeder <webmaster@shipsimu.org>
+ * @version 0.0.0
+ * @copyright Copyright (c) 2007, 2008 Roland Haeder, 2009 - 2018 Hub Developer Team
+ * @license GNU GPL 3.0 or any newer version
+ * @link http://www.shipsimu.org
+ * @todo Needs to add functionality for handling the object's type
+ *
+ * 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 NetworkPackageHandler extends BaseHubHandler implements Deliverable, Receivable, Registerable, Visitable {
+ /**
+ * Package mask for compressing package data:
+ * 0: Compressor extension
+ * 1: Raw package data
+ * 2: Tags, seperated by semicolons, no semicolon is required if only one tag is needed
+ * 3: Checksum
+ * 0 1 2 3
+ */
+ const PACKAGE_MASK = '%s%s%s%s%s%s%s';
+
+ /**
+ * Separator for the above mask
+ */
+ const PACKAGE_MASK_SEPARATOR = '^';
+
+ /**
+ * Size of an array created by invoking
+ * explode(NetworkPackageHandler::PACKAGE_MASK_SEPARATOR, $content).
+ */
+ const PACKAGE_CONTENT_ARRAY_SIZE = 4;
+
+ /**
+ * Separator for checksum
+ */
+ const PACKAGE_CHECKSUM_SEPARATOR = '_';
+
+ /**
+ * Array indexes for above mask, start with zero
+ */
+ const INDEX_COMPRESSOR_EXTENSION = 0;
+ const INDEX_PACKAGE_DATA = 1;
+ const INDEX_TAGS = 2;
+ const INDEX_CHECKSUM = 3;
+
+ /**
+ * Array indexes for raw package array
+ */
+ const INDEX_PACKAGE_SENDER_ADDRESS = 0;
+ const INDEX_PACKAGE_SENDER_PORT = 1;
+ const INDEX_PACKAGE_RECIPIENT = 2;
+ const INDEX_PACKAGE_CONTENT = 3;
+ const INDEX_PACKAGE_STATUS = 4;
+ const INDEX_PACKAGE_HASH = 5;
+ const INDEX_PACKAGE_PRIVATE_KEY_HASH = 6;
+
+ /**
+ * Size of the decoded data array
+ */
+ const DECODED_DATA_ARRAY_SIZE = 6;
+
+ /**
+ * 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';
+ const PACKAGE_CONTENT_SENDER = 'sender';
+ const PACKAGE_CONTENT_HASH = 'hash';
+ const PACKAGE_CONTENT_PRIVATE_KEY_HASH = 'pkhash';
+
+ /**
+ * All package status
+ */
+ const PACKAGE_STATUS_NEW = 'new';
+ const PACKAGE_STATUS_FAILED = 'failed';
+ const PACKAGE_STATUS_DECODED = 'decoded';
+ const PACKAGE_STATUS_FAKED = 'faked';
+
+ /**
+ * Constants for message data array
+ */
+ const MESSAGE_ARRAY_DATA = 'message_data';
+ const MESSAGE_ARRAY_TYPE = 'message_type';
+ const MESSAGE_ARRAY_SENDER = 'message_sender';
+ const MESSAGE_ARRAY_HASH = 'message_hash';
+ const MESSAGE_ARRAY_TAGS = 'message_tags';
+ const MESSAGE_ARRAY_DATA_NODE_ID = 'node-id';
+
+ /**
+ * Generic answer status field
+ */
+
+ /**
+ * Tags separator
+ */
+ const PACKAGE_TAGS_SEPARATOR = ';';
+
+ /**
+ * Raw package data separator
+ */
+ const PACKAGE_DATA_SEPARATOR = '#';
+
+ /**
+ * Separator for more than one recipient
+ */
+ const PACKAGE_RECIPIENT_SEPARATOR = ':';
+
+ /**
+ * Network target (alias): 'upper nodes'
+ */
+ const NETWORK_TARGET_UPPER = 'upper';
+
+ /**
+ * Network target (alias): 'self'
+ */
+ const NETWORK_TARGET_SELF = 'self';
+
+ /**
+ * Network target (alias): 'dht'
+ */
+ const NETWORK_TARGET_DHT = 'dht';
+
+ /**
+ * TCP package size in bytes
+ */
+ const TCP_PACKAGE_SIZE = 512;
+
+ /**************************************************************************
+ * Stacker for out-going packages *
+ **************************************************************************/
+
+ /**
+ * Stacker name for "undeclared" packages
+ */
+ const STACKER_NAME_UNDECLARED = 'package_undeclared';
+
+ /**
+ * Stacker name for "declared" packages (which are ready to send out)
+ */
+ const STACKER_NAME_DECLARED = 'package_declared';
+
+ /**
+ * Stacker name for "out-going" packages
+ */
+ const STACKER_NAME_OUTGOING = 'package_outgoing';
+
+ /**************************************************************************
+ * Stacker for incoming packages *
+ **************************************************************************/
+
+ /**
+ * Stacker name for "incoming" decoded raw data
+ */
+ const STACKER_NAME_DECODED_INCOMING = 'package_decoded_data';
+
+ /**
+ * Stacker name for handled decoded raw data
+ */
+ const STACKER_NAME_DECODED_HANDLED = 'package_handled_decoded';
+
+ /**
+ * Stacker name for "chunked" decoded raw data
+ */
+ const STACKER_NAME_DECODED_CHUNKED = 'package_chunked_decoded';
+
+ /**************************************************************************
+ * Stacker for incoming messages *
+ **************************************************************************/
+
+ /**
+ * Stacker name for new messages
+ */
+ const STACKER_NAME_NEW_MESSAGE = 'package_new_message';
+
+ /**
+ * Stacker name for processed messages
+ */
+ const STACKER_NAME_PROCESSED_MESSAGE = 'package_processed_message';
+
+ /**************************************************************************
+ * Stacker for raw data handling *
+ **************************************************************************/
+
+ /**
+ * Stacker for outgoing data stream
+ */
+ const STACKER_NAME_OUTGOING_STREAM = 'outgoing_stream';
+
+ /**
+ * Array index for final hash
+ */
+ const RAW_INDEX_FINAL_HASH = 'hash';
+
+ /**
+ * Array index for encoded data
+ */
+ const RAW_INDEX_ENCODED_DATA = 'data';
+
+ /**
+ * Array index for sent bytes
+ */
+ const RAW_INDEX_SENT_BYTES = 'sent';
+
+ /**
+ * Array index for socket resource
+ */
+ const RAW_INDEX_SOCKET_INSTANCE = 'socket';
+
+ /**
+ * Array index for buffer size
+ */
+ const RAW_INDEX_BUFFER_SIZE = 'buffer';
+
+ /**
+ * Array index for diff between buffer and sent bytes
+ */
+ const RAW_INDEX_DIFF = 'diff';
+
+ /**************************************************************************
+ * Protocol names *
+ **************************************************************************/
+ const PROTOCOL_TCP = 'TCP';
+ const PROTOCOL_UDP = 'UDP';
+
+ /**************************************************************************
+ * Exception codes *
+ **************************************************************************/
+ const EXCEPTION_UNEXPECTED_PACKAGE_STATUS = 0xff00;
+ const EXCEPTION_INVALID_DATA_CHECKSUM = 0xff01;
+
+ /**
+ * Protected constructor
+ *
+ * @return void
+ */
+ protected function __construct () {
+ // Call parent constructor
+ parent::__construct(__CLASS__);
+
+ // The socket needs to be put in a special registry that can handle such data
+ $registryInstance = SocketRegistryFactory::createSocketRegistryInstance();
+
+ // Set it here
+ $this->setRegistryInstance($registryInstance);
+ }
+
+ /**
+ * Creates an instance of this class
+ *
+ * @param $compressorInstance A Compressor instance for compressing the content
+ * @return $packageInstance An instance of a Deliverable class
+ */
+ public static final function createNetworkPackageHandler (Compressor $compressorInstance) {
+ // Get new instance
+ $packageInstance = new NetworkPackageHandler();
+
+ // Now set the compressor instance
+ $packageInstance->setCompressorInstance($compressorInstance);
+
+ /*
+ * We need to initialize a stack here for our packages even for those
+ * which have no recipient address and stamp... ;-) This stacker will
+ * also be used for incoming raw data to handle it.
+ */
+ $stackInstance = ObjectFactory::createObjectByConfiguredName('network_package_stacker_class');
+
+ // At last, set it in this class
+ $packageInstance->setStackInstance($stackInstance);
+
+ // Init all stacker
+ $packageInstance->initStacks();
+
+ // Get a visitor instance for speeding up things and set it
+ $visitorInstance = ObjectFactory::createObjectByConfiguredName('node_raw_data_monitor_visitor_class');
+ $packageInstance->setVisitorInstance($visitorInstance);
+
+ // Get crypto instance and set it, too
+ $cryptoInstance = ObjectFactory::createObjectByConfiguredName('crypto_class');
+ $packageInstance->setCryptoInstance($cryptoInstance);
+
+ // Get a singleton package assembler instance from factory and set it here, too
+ $assemblerInstance = PackageAssemblerFactory::createAssemblerInstance($packageInstance);
+ $packageInstance->setAssemblerInstance($assemblerInstance);
+
+ // Get node instance
+ $nodeInstance = NodeObjectFactory::createNodeInstance();
+
+ // Get pool instance from node
+ $poolInstance = $nodeInstance->getListenerPoolInstance();
+
+ // And set it here
+ $packageInstance->setListenerPoolInstance($poolInstance);
+
+ // Return the prepared instance
+ return $packageInstance;
+ }
+
+ /**
+ * Initialize all stackers
+ *
+ * @param $forceReInit Whether to force reinitialization of all stacks
+ * @return void
+ */
+ protected function initStacks ($forceReInit = FALSE) {
+ // Initialize all
+ $this->getStackInstance()->initStacks(array(
+ self::STACKER_NAME_UNDECLARED,
+ self::STACKER_NAME_DECLARED,
+ self::STACKER_NAME_OUTGOING,
+ self::STACKER_NAME_DECODED_INCOMING,
+ self::STACKER_NAME_DECODED_HANDLED,
+ self::STACKER_NAME_DECODED_CHUNKED,
+ self::STACKER_NAME_NEW_MESSAGE,
+ self::STACKER_NAME_PROCESSED_MESSAGE,
+ self::STACKER_NAME_OUTGOING_STREAM
+ ), $forceReInit);
+ }
+
+ /**
+ * Determines private key hash from given session id
+ *
+ * @param $packageInstance An instance of a DeliverablePackage class
+ * @return $hash Private key's hash
+ * @throws InvalidPrivateKeyHashException If the private key's hash is not valid
+ */
+ private function determineSenderPrivateKeyHash (DeliverablePackage $packageInstance) {
+ // Get DHT instance
+ $dhtInstance = DhtObjectFactory::createDhtInstance('node');
+
+ // Ask DHT for session id
+ $senderData = $dhtInstance->findNodeLocalBySessionId($packageInstance->getContentSender());
+
+ // Debugging:
+ //* DEBUG-DIE: */ die(sprintf('[%s:%d]: senderData=%s', __METHOD__, __LINE__, print_r($senderData, TRUE)));
+
+ // Is an entry found?
+ if (count($senderData) > 0) {
+ // Make sure the element 'private_key_hash' is there
+ //* NOISY-DEBUG */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('NETWORK-PACKAGE: senderData=' . print_r($senderData, TRUE));
+ assert(isset($senderData[NodeDistributedHashTableDatabaseWrapper::DB_COLUMN_PRIVATE_KEY_HASH]));
+
+ // Don't accept empty hashes
+ if (empty($senderData[NodeDistributedHashTableDatabaseWrapper::DB_COLUMN_PRIVATE_KEY_HASH])) {
+ // Don't accept
+ throw new InvalidPrivateKeyHashException(array($this, $senderData, 'empty hash in senderData'), self::EXCEPTION_INVALID_PRIVATE_KEY_HASH);
+ } // END - if
+
+ // Return it
+ return $senderData[NodeDistributedHashTableDatabaseWrapper::DB_COLUMN_PRIVATE_KEY_HASH];
+ } // END - if
+
+ // Don't accept empty keys
+ if (empty($packageInstance->getContentPrivateKeyHash())) {
+ // This needs fixing
+ throw new InvalidPrivateKeyHashException(array($this, $senderData, 'empty hash in decodedData'), self::EXCEPTION_INVALID_PRIVATE_KEY_HASH);
+ } // END - if
+
+ // There is no DHT entry so, accept the hash from decoded data
+ return $packageInstance->getContentPrivateKeyHash();
+ }
+
+ /**
+ * "Getter" for hash from given content
+ *
+ * @param $content Raw package content
+ * @return $hash Hash for given package content
+ */
+ private function getHashFromContent ($content) {
+ // Debug message
+ //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('NETWORK-PACKAGE: content[md5]=' . md5($content) . ',sender=' . $this->getSessionId() . ',compressor=' . $this->getCompressorInstance()->getCompressorExtension());
+
+ // Create the hash
+ // @TODO md5() is very weak, but it needs to be fast
+ $hash = md5(
+ $content .
+ self::PACKAGE_CHECKSUM_SEPARATOR .
+ $this->getSessionId() .
+ self::PACKAGE_CHECKSUM_SEPARATOR .
+ $this->getCompressorInstance()->getCompressorExtension()
+ );
+
+ // Debug message
+ //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('NETWORK-PACKAGE: content[md5]=' . md5($content) . ',sender=' . $this->getSessionId() . ',hash=' . $hash . ',compressor=' . $this->getCompressorInstance()->getCompressorExtension());
+
+ // And return it
+ return $hash;
+ }
+
+ /**
+ * Checks whether the checksum (sometimes called "hash") is the same
+ *
+ * @param $decodedContent Package raw content
+ * @param $packageInstance An instance of a DeliverablePackage class
+ * @return $isChecksumValid Whether the checksum is the same
+ */
+ private function isChecksumValid (array $decodedContent, DeliverablePackage $packageInstance) {
+ // Get checksum
+ $checksum = $this->getHashFromContentSessionId($decodedContent, $packageInstance->getSenderAddress());
+
+ // Is it the same?
+ $isChecksumValid = ($checksum == $decodedContent[self::PACKAGE_CONTENT_CHECKSUM]);
+
+ // Return it
+ return $isChecksumValid;
+ }
+
+ /**
+ * Change the package with given status in given stack
+ *
+ * @param $packageInstance An instance of a DeliverablePackage class in an array
+ * @param $stackerName Name of the stacker
+ * @param $newStatus New status to set
+ * @return void
+ */
+ private function changePackageStatus (DeliverablePackage $packageInstance, $stackerName, $newStatus) {
+ // Skip this for empty stacks
+ if ($this->getStackInstance()->isStackEmpty($stackerName)) {
+ // This avoids an exception after all packages has failed
+ return;
+ } // END - if
+
+ // Pop the entry (it should be it)
+ $nextData = $this->getStackInstance()->popNamed($stackerName);
+
+ // Compare both hashes
+ assert($nextData->getPackageHash() == $packageInstance->getPackageHash());
+
+ // Temporary set the new status
+ $packageInstance->setPackageStatus($newStatus);
+
+ // And push it again
+ $this->getStackInstance()->pushNamed($stackerName, $packageInstance);
+ }
+
+ /**
+ * "Getter" for hash from given content and sender's session id
+ *
+ * @param $decodedContent Raw 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: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('NETWORK-PACKAGE: content[md5]=' . md5($decodedContent[self::PACKAGE_CONTENT_MESSAGE]) . ',sender=' . $sessionId . ',compressor=' . $decodedContent[self::PACKAGE_CONTENT_EXTENSION]);
+
+ // Create the hash
+ // @TODO md5() is very weak, but it needs to be fast
+ $hash = md5(
+ $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
+ ///////////////////////////////////////////////////////////////////////////
+
+ /**
+ * Declares the given An instance of a DeliverablePackage class by discovering recipients
+ *
+ * @param $packageData An instance of a DeliverablePackage class in an array
+ * @return void
+ */
+ private function declareRawPackageData (DeliverablePackage $packageInstance) {
+ /*
+ * We need to disover every recipient, just in case we have a
+ * multi-recipient entry like 'upper' is. 'all' may be a not so good
+ * target because it causes an overload on the network and may be
+ * abused for attacking the network with large packages.
+ */
+ $discoveryInstance = PackageDiscoveryFactory::createPackageDiscoveryInstance();
+
+ // Discover all recipients, this may throw an exception
+ $discoveryInstance->discoverRecipients($packageData);
+
+ // Now get an iterator
+ $iteratorInstance = $discoveryInstance->getIterator();
+
+ // Make sure the iterator instance is valid
+ assert($iteratorInstance instanceof Iterator);
+
+ // Rewind back to the beginning
+ $iteratorInstance->rewind();
+
+ // ... and begin iteration
+ while ($iteratorInstance->valid()) {
+ // Get current entry
+ $currentRecipient = $iteratorInstance->current();
+
+ // Debug message
+ //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('NETWORK-PACKAGE: Setting recipient to ' . $currentRecipient . ',previous=' . packageInstance->getRecipient());
+
+ // Set the recipient
+ $packageInstance->setRecipient($currentRecipient);
+
+ // Push the declared package to the next stack.
+ $this->getStackInstance()->pushNamed(self::STACKER_NAME_DECLARED, $packageData);
+
+ // Debug message
+ //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('NETWORK-PACKAGE: Package declared for recipient ' . $currentRecipient);
+
+ // Skip to next entry
+ $iteratorInstance->next();
+ } // END - while
+
+ /*
+ * The recipient list can be cleaned up here because the package which
+ * shall be delivered has already been added for all entries from the
+ * list.
+ */
+ $discoveryInstance->clearRecipients();
+ }
+
+ /**
+ * Delivers raw package data. In short, this will discover the raw socket
+ * resource through a discovery class (which will analyse the receipient of
+ * the package), register the socket with the connection (handler/helper?)
+ * instance and finally push the raw data on our outgoing queue.
+ *
+ * @param $packageData An instance of a DeliverablePackage class in an array
+ * @return void
+ */
+ private function deliverRawPackageData (DeliverablePackage $packageInstance) {
+ // Trace message
+ //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('NETWORK-PACKAGE: packageData()=%d - CALLED!', count($packageData)));
+
+ /*
+ * This package may become big, depending on the shared object size or
+ * delivered message size which shouldn't be so long (to save
+ * bandwidth). Because of the nature of the used protocol (TCP) we need
+ * to split it up into smaller pieces to fit it into a TCP frame.
+ *
+ * So first we need (again) a discovery class but now a protocol
+ * discovery to choose the right socket resource. The discovery class
+ * should take a look at the raw package data itself and then decide
+ * which (configurable!) protocol should be used for that type of
+ * package.
+ */
+ $discoveryInstance = SocketDiscoveryFactory::createSocketDiscoveryInstance();
+
+ // Now discover the right socket instance from given package data
+ $socketInstance = $discoveryInstance->discoverSocket($packageData, StorableSocket::CONNECTION_TYPE_OUTGOING);
+
+ // Debug message
+ //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('NETWORK-PACKAGE: Reached line ' . __LINE__ . ' after discoverSocket() has been called.');
+
+ // Get the connection helper from registry
+ $helperInstance = GenericRegistry::getRegistry()->getInstance('connection');
+
+ // Debug message
+ //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('NETWORK-PACKAGE: stateInstance=' . $helperInstance->getStateInstance());
+
+ // And make sure it is valid
+ assert($helperInstance instanceof ConnectionHelper);
+
+ // Get connection info class
+ $infoInstance = ConnectionInfoFactory::createConnectionInfoInstance($helperInstance->getProtocolName(), 'helper');
+
+ // Will the info instance with connection helper data
+ $infoInstance->fillWithConnectionHelperInformation($helperInstance);
+
+ // Debug message
+ //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('NETWORK-PACKAGE: Reached line ' . __LINE__ . ' before isSocketRegistered() has been called.');
+
+ // Is it not there?
+ if (($socketInstance->isValidSocket()) && (!$this->getRegistryInstance()->isSocketRegistered($infoInstance, $socketInstance))) {
+ // Debug message
+ //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('NETWORK-PACKAGE: Registering socket ' . $socketInstance . ' ...');
+
+ // Then register it
+ $this->getRegistryInstance()->registerSocketInstance($infoInstance, $socketInstance);
+ } elseif (!$helperInstance->getStateInstance()->isPeerStateConnected()) {
+ // Is not connected, then we cannot send
+ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('NETWORK-PACKAGE: Unexpected peer state ' . $helperInstance->getStateInstance()->__toString() . ' detected.');
+
+ // Shutdown the socket
+ $socketInstance->shutdownSocket();
+ }
+
+ // Debug message
+ //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('NETWORK-PACKAGE: Reached line ' . __LINE__ . ' after isSocketRegistered() has been called.');
+
+ // Make sure the connection is up
+ $helperInstance->getStateInstance()->validatePeerStateConnected();
+
+ // Debug message
+ //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('NETWORK-PACKAGE: Reached line ' . __LINE__ . ' after validatePeerStateConnected() has been called.');
+
+ // Enqueue it again on the out-going queue, the connection is up and working at this point
+ $this->getStackInstance()->pushNamed(self::STACKER_NAME_OUTGOING, $packageData);
+
+ // Debug message
+ //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('NETWORK-PACKAGE: Reached line ' . __LINE__ . ' after pushNamed() has been called.');
+ }
+
+ /**
+ * Sends waiting packages
+ *
+ * @param $packageData An instance of a DeliverablePackage class
+ * @return void
+ */
+ private function sendOutgoingRawPackageData (DeliverablePackage $packageInstance) {
+ // Trace message
+ //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('NETWORK-PACKAGE: packageData()=%d - CALLED!', count($packageData)));
+
+ // Init sent bytes
+ $sentBytes = 0;
+
+ // Get the right connection instance
+ $infoInstance = $this->getRegistryInstance()->getInfoInstanceFromPackageInstance($packageData);
+
+ // Test helper instance
+ assert($infoInstance instanceof ShareableInfo);
+
+ // Get helper instance
+ $helperInstance = $infoInstance->getHelperInstance();
+
+ // Some sanity-checks on the object
+ //* DEBUG-DIE: */ die(': p1=' . $infoInstance->getProtocolName() . ',p2=' . $helperInstance->getProtocolName() . ',infoInstance=' . print_r($infoInstance, TRUE));
+ assert($helperInstance instanceof ConnectionHelper);
+ assert($infoInstance->getProtocolName() == $helperInstance->getProtocolName());
+
+ // Is this connection still alive?
+ if ($helperInstance->isShuttedDown()) {
+ // This connection is shutting down
+ // @TODO We may want to do somthing more here?
+ return;
+ } // END - if
+
+ // Sent out package data
+ $helperInstance->sendRawPackageData($packageData);
+
+ // Debug message
+ //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('NETWORK-PACKAGE: EXIT!');
+ }
+
+ /**
+ * Generates a secure hash for given raw package content and sender id
+ *
+ * @param $content An instance of a DeliverablePackage class
+ * @param $senderId Sender id to generate a hash for
+ * @return $hash Hash as hex-encoded string
+ */
+ private function generatePackageHash ($content, $senderId) {
+ // Debug message
+ //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('NETWORK-PACKAGE: content()=' . strlen($content) . ',senderId=' . $senderId . ' - CALLED!');
+
+ // Assert on variables
+ assert(!empty($content));
+ assert(!empty($senderId));
+
+ // Is the feature enabled?
+ if (!FrameworkFeature::isFeatureAvailable('hubcoin_reward')) {
+ // Feature is not enabled
+ //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('NETWORK-PACKAGE: Feature "hubcoin_reward" not available, not generating package hash. Returning NULL ...');
+ return NULL;
+ } // END - if
+
+ // Fake array
+ $data = array(
+ self::PACKAGE_CONTENT_SENDER => $senderId,
+ self::PACKAGE_CONTENT_MESSAGE => $content,
+ self::PACKAGE_CONTENT_PRIVATE_KEY_HASH => $this->getPrivateKeyHash(),
+ );
+
+ // Hash content and sender id together, use scrypt
+ //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('NETWORK-PACKAGE: senderId=' . $senderId . ',content()=' . strlen($content));
+ $hash = FrameworkFeature::callFeature('hubcoin_reward', 'generateHash', array($senderId . ':' . $content . ':' . $this->determineSenderPrivateKeyHash($data)));
+
+ // Debug message
+ //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('NETWORK-PACKAGE: hash=' . $hash . ' - EXIT!');
+
+ // Return it
+ return $hash;
+ }
+
+ /**
+ * Checks whether the hash 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 $isHashValid Whether the hash is valid
+ * @todo Unfinished area, hashes are currently NOT fully supported
+ */
+ private function isPackageHashValid (array $decodedArray) {
+ // Debug message
+ //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('NETWORK-PACKAGE: decodedArray=' . print_r($decodedArray, TRUE) . ' - CALLED!');
+
+ // Make sure the required array elements are there
+ assert(isset($decodedArray[self::PACKAGE_CONTENT_SENDER]));
+ assert(isset($decodedArray[self::PACKAGE_CONTENT_MESSAGE]));
+ assert(isset($decodedArray[self::PACKAGE_CONTENT_HASH]));
+ assert(isset($decodedArray[self::PACKAGE_CONTENT_PRIVATE_KEY_HASH]));
+
+ // Is the feature enabled?
+ if (!FrameworkFeature::isFeatureAvailable('hubcoin_reward')) {
+ // Feature is not enabled, so hashes are always valid
+ //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('NETWORK-PACKAGE: Feature "hubcoin_reward" not available, not checking hash. Returning TRUE ...');
+ return TRUE;
+ } // END - if
+
+ // Check validity
+ //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('NETWORK-PACKAGE: senderId=' . $decodedArray[self::PACKAGE_CONTENT_SENDER] . ',message()=' . strlen($decodedArray[self::PACKAGE_CONTENT_MESSAGE]) . ',hash=' . $decodedArray[self::PACKAGE_CONTENT_HASH]);
+ //* DEBUG-DIE: */ die(__METHOD__ . ': decodedArray=' . print_r($decodedArray, TRUE));
+ $isHashValid = FrameworkFeature::callFeature('hubcoin_reward', 'checkHash', array($decodedArray[self::PACKAGE_CONTENT_SENDER] . ':' . $decodedArray[self::PACKAGE_CONTENT_MESSAGE] . ':' . $this->determineSenderPrivateKeyHash($decodedArray), $decodedArray[self::PACKAGE_CONTENT_HASH]));
+
+ // Return it
+ //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('NETWORK-PACKAGE: isHashValid=' . intval($isHashValid) . ' - EXIT!');
+ return $isHashValid;
+ }
+
+ /**
+ * "Enqueues" raw content into this delivery class by reading the raw content
+ * from given helper's template instance and pushing it on the 'undeclared'
+ * stack.
+ *
+ * @param $helperInstance An instance of a HubHelper class
+ * @return void
+ */
+ public function enqueueRawDataFromTemplate (HubHelper $helperInstance) {
+ // Debug message
+ //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('NETWORK-PACKAGE: CALLED!');
+
+ // Get the raw content ...
+ $content = $helperInstance->getTemplateInstance()->getRawTemplateData();
+ //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('content(' . strlen($content) . ')=' . $content);
+
+ // ... and compress it
+ $compressed = $this->getCompressorInstance()->compressStream($content);
+
+ // Add magic in front of it and hash behind it, including BASE64 encoding
+ $packageContent = sprintf(self::PACKAGE_MASK,
+ // 1.) Compressor's extension
+ $this->getCompressorInstance()->getCompressorExtension(),
+ // - separator
+ self::PACKAGE_MASK_SEPARATOR,
+ // 2.) Compressed raw package content, encoded with BASE64
+ base64_encode($compressed),
+ // - separator
+ self::PACKAGE_MASK_SEPARATOR,
+ // 3.) Tags
+ implode(self::PACKAGE_TAGS_SEPARATOR, $helperInstance->getPackageTags()),
+ // - separator
+ self::PACKAGE_MASK_SEPARATOR,
+ // 4.) Checksum
+ $this->getHashFromContent($compressed)
+ );
+
+ // Debug message
+ //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('NETWORK-PACKAGE: Enqueueing package for recipientType=' . $helperInstance->getRecipientType() . ' ...');
+
+ // Make sure required data is there
+ assert(!empty($content));
+ assert($this->getSessionId() != '');
+
+ // Init package instance
+ $packageInstance = PackageDataFactory::createDeliverPackageInstance();
+
+ // Set all data
+ $packageInstance->setSenderAddress($this->getSessionId());
+ $packageInstance->setSenderPort('0');
+ $packageInstance->setRecipientType($helperInstance->getRecipientType());
+ $packageInstance->setContent($packageContent);
+ $packageInstance->setStatus(self::PACKAGE_STATUS_NEW);
+ $packageInstance->setHash($this->generatePackageHash($content, $this->getSessionId()));
+ $packageInstance->setPrivateKeyHash($this->getPrivateKeyHash());
+
+ // Now prepare the temporary array and push it on the 'undeclared' stack
+ $this->getStackInstance()->pushNamed(self::STACKER_NAME_UNDECLARED, $packageInstance);
+
+ // Debug message
+ //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('NETWORK-PACKAGE: EXIT!');
+ }
+
+ /**
+ * Checks whether a package has been enqueued for delivery.
+ *
+ * @return $isEnqueued Whether a package is enqueued
+ */
+ public function isPackageEnqueued () {
+ // Check whether the stacker is not empty
+ $isEnqueued = (($this->getStackInstance()->isStackInitialized(self::STACKER_NAME_UNDECLARED)) && (!$this->getStackInstance()->isStackEmpty(self::STACKER_NAME_UNDECLARED)));
+
+ // Trace message
+ //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('NETWORK-PACKAGE: isEnqueued=%d - EXIT!', intval($isEnqueued)));
+
+ // Return the result
+ return $isEnqueued;
+ }
+
+ /**
+ * Checks whether a package has been declared
+ *
+ * @return $isDeclared Whether a package is declared
+ */
+ public function isPackageDeclared () {
+ // Check whether the stacker is not empty
+ $isDeclared = (($this->getStackInstance()->isStackInitialized(self::STACKER_NAME_DECLARED)) && (!$this->getStackInstance()->isStackEmpty(self::STACKER_NAME_DECLARED)));
+
+ // Trace message
+ //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('NETWORK-PACKAGE: isDeclared=%d - EXIT!', intval($isDeclared)));
+
+ // Return the result
+ return $isDeclared;
+ }
+
+ /**
+ * Checks whether a package should be sent out
+ *
+ * @return $isWaitingDelivery Whether a package is waiting for delivery
+ */
+ public function isPackageWaitingForDelivery () {
+ // Check whether the stacker is not empty
+ $isWaitingDelivery = (($this->getStackInstance()->isStackInitialized(self::STACKER_NAME_OUTGOING)) && (!$this->getStackInstance()->isStackEmpty(self::STACKER_NAME_OUTGOING)));
+
+ // Trace message
+ //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('NETWORK-PACKAGE: isWaitingDelivery=%d - EXIT!', intval($isWaitingDelivery)));
+
+ // Return the result
+ return $isWaitingDelivery;
+ }
+
+ /**
+ * Checks whether encoded (raw) data is pending
+ *
+ * @return $isPending Whether encoded data is pending
+ */
+ public function isEncodedDataPending () {
+ // Check whether the stacker is not empty
+ $isPending = (($this->getStackInstance()->isStackInitialized(self::STACKER_NAME_OUTGOING_STREAM)) && (!$this->getStackInstance()->isStackEmpty(self::STACKER_NAME_OUTGOING_STREAM)));
+
+ // Trace message
+ //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('NETWORK-PACKAGE: isPending=%d - EXIT!', intval($isPending)));
+
+ // Return the result
+ return $isPending;
+ }
+
+ /**
+ * Delivers an enqueued package to the stated destination. If a non-session
+ * id is provided, recipient resolver is being asked (and instanced once).
+ * This allows that a single package is being delivered to multiple targets
+ * without enqueueing it for every target. If no target is provided or it
+ * can't be determined a NoTargetException is being thrown.
+ *
+ * @return void
+ * @throws NoTargetException If no target can't be determined
+ */
+ public function declareEnqueuedPackage () {
+ // Debug message
+ //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('NETWORK-PACKAGE: CALLED!');
+
+ // Make sure this method isn't working if there is no package enqueued
+ if (!$this->isPackageEnqueued()) {
+ // This is not fatal but should be avoided
+ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('NETWORK-PACKAGE: No raw package data waiting declaration, but ' . __METHOD__ . ' has been called!');
+ return;
+ } // END - if
+
+ /*
+ * Now there are for sure packages to deliver, so start with the first
+ * one.
+ */
+ $packageData = $this->getStackInstance()->popNamed(self::STACKER_NAME_UNDECLARED);
+
+ // Declare the raw package data for delivery
+ $this->declareRawPackageData($packageData);
+
+ // Debug message
+ //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('NETWORK-PACKAGE: EXIT!');
+ }
+
+ /**
+ * Delivers the next declared package. Only one package per time will be sent
+ * because this may take time and slows down the whole delivery
+ * infrastructure.
+ *
+ * @return void
+ */
+ public function processDeclaredPackage () {
+ // Debug message
+ //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('NETWORK-PACKAGE: CALLED!');
+
+ // Sanity check if we have packages declared
+ if (!$this->isPackageDeclared()) {
+ // This is not fatal but should be avoided
+ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('NETWORK-PACKAGE: No package has been declared, but ' . __METHOD__ . ' has been called!');
+ return;
+ } // END - if
+
+ // Get the package instance
+ $packageInstance = $this->getStackInstance()->getNamed(self::STACKER_NAME_DECLARED);
+
+ // Try to deliver the package
+ try {
+ // And try to send it
+ $this->deliverRawPackageData($packageInstance);
+
+ // And remove it finally
+ $this->getStackInstance()->popNamed(self::STACKER_NAME_DECLARED);
+ } catch (UnexpectedStateException $e) {
+ // The state is not excepected (shall be 'connected')
+ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('NETWORK-PACKAGE: Caught ' . $e->__toString() . ',message=' . $e->getMessage());
+
+ // Mark the package with status failed
+ $this->changePackageStatus($packageInstance, self::STACKER_NAME_DECLARED, self::PACKAGE_STATUS_FAILED);
+ }
+
+ // Debug message
+ //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('NETWORK-PACKAGE: EXIT!');
+ }
+
+ /**
+ * Sends waiting packages out for delivery
+ *
+ * @return void
+ */
+ public function sendWaitingPackage () {
+ // Debug message
+ //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('NETWORK-PACKAGE: CALLED!');
+
+ // Sanity check if we have packages waiting for delivery
+ if (!$this->isPackageWaitingForDelivery()) {
+ // This is not fatal but should be avoided
+ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('NETWORK-PACKAGE: No package is waiting for delivery, but ' . __METHOD__ . ' was called.');
+ return;
+ } // END - if
+
+ // Get the package
+ $packageInstance = $this->getStackInstance()->getNamed(self::STACKER_NAME_OUTGOING);
+
+ try {
+ // Now try to send it
+ $this->sendOutgoingRawPackageData($packageInstance);
+
+ // And remove it finally
+ $this->getStackInstance()->popNamed(self::STACKER_NAME_OUTGOING);
+ } catch (InvalidSocketException $e) {
+ // Output exception message
+ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('NETWORK-PACKAGE: Package was not delivered: ' . $e->getMessage());
+
+ // Mark package as failed
+ $this->changePackageStatus($packageInstance, self::STACKER_NAME_OUTGOING, self::PACKAGE_STATUS_FAILED);
+ }
+
+ // Debug message
+ //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('NETWORK-PACKAGE: EXIT!');
+ }
+
+ /**
+ * Sends out encoded data to a socket
+ *
+ * @return void
+ */
+ public function sendEncodedData () {
+ // Debug message
+ /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('NETWORK-PACKAGE: CALLED!');
+
+ // Make sure there is pending encoded data
+ assert($this->isEncodedDataPending());
+
+ // Pop current data from stack
+ $encodedDataArray = $this->getStackInstance()->popNamed(self::STACKER_NAME_OUTGOING_STREAM);
+
+ // Init in this round sent bytes
+ $sentBytes = 0;
+
+ // Assert on socket instance
+ assert(isset($encodedDataArray[self::RAW_INDEX_SOCKET_INSTANCE]));
+ assert($encodedDataArray[self::RAW_INDEX_SOCKET_INSTANCE] instanceof StorableSocket);
+ assert($encodedDataArray[self::RAW_INDEX_SOCKET_INSTANCE]->isValidSocket());
+
+ // Get socket instance and remove it from array
+ $socketInstance = $encodedDataArray[self::RAW_INDEX_SOCKET_INSTANCE];
+ $encodedDataArray[self::RAW_INDEX_SOCKET_INSTANCE] = NULL;
+
+ // Trace message
+ /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('NETWORK-PACKAGE: Calling socketInstance->writeBufferToSocketByArray(%d,%d) ...', count($encodedDataArray), $sentBytes));
+
+ // And deliver it
+ if (!$socketInstance->writeBufferToSocketByArray($encodedDataArray, $sentBytes)) {
+ // Something bad happened while writing to socket
+ $socketInstance->handleSocketError(__METHOD__, __LINE__, array('0.0.0.0', '0'));
+ } // END - if
+
+ // Debug message
+ /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('NETWORK-PACKAGE: sentBytes[%s]=%d', gettype($sentBytes), $sentBytes));
+
+ // If there was an error, don't continue here
+ if (($sentBytes === 0) && (strlen($encodedDataArray[self::RAW_INDEX_ENCODED_DATA]) > 0)) {
+ // Nothing sent means all data has been sent
+ /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('CONNECTION-HELPER: All sent! (LINE=' . __LINE__ . ')');
+ return;
+ } elseif (strlen($encodedDataArray[self::RAW_INDEX_ENCODED_DATA]) == 0) {
+ // Abort here, all sent!
+ /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('CONNECTION-HELPER: All sent! (LINE=' . __LINE__ . ')');
+ return;
+ }
+
+ // Set it back
+ $encodedDataArray[self::RAW_INDEX_SOCKET_INSTANCE] = $socketInstance;
+
+ // Debug message
+ /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('CONNECTION-HELPER: Pushing raw data back to stacker, as still some data is pending delivery.');
+
+ // Push array back in stack
+ $this->getStackInstance()->pushNamed(self::STACKER_NAME_OUTGOING_STREAM, $encodedDataArray);
+
+ // Debug message
+ /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('NETWORK-PACKAGE: EXIT!');
+ }
+
+ ///////////////////////////////////////////////////////////////////////////
+ // Receiving packages / raw data
+ ///////////////////////////////////////////////////////////////////////////
+
+ /**
+ * Checks whether decoded raw data is pending
+ *
+ * @return $isPending Whether decoded raw data is pending
+ */
+ private function isRawDataPending () {
+ // Trace message
+ //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('NETWORK-PACKAGE: CALLED!');
+
+ // Just return whether the stack is not empty
+ $isPending = (!$this->getStackInstance()->isStackEmpty(self::STACKER_NAME_DECODED_INCOMING));
+
+ // Trace message
+ //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('NETWORK-PACKAGE: isPending=%d - EXIT!', intval($isPending)));
+
+ // Return the status
+ return $isPending;
+ }
+
+ /**
+ * Checks whether new raw package data has arrived at a socket
+ *
+ * @return $hasArrived Whether new raw package data has arrived for processing
+ */
+ public function isNewRawDataPending () {
+ // Trace message
+ //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('NETWORK-PACKAGE: Calling this->getListenerPoolInstance()->accept(%s) ... - CALLED!', $this->getVisitorInstance()));
+
+ // Visit the pool. This monitors the pool for incoming raw data.
+ $this->getListenerPoolInstance()->accept($this->getVisitorInstance());
+
+ // Check for new data arrival
+ $hasArrived = $this->isRawDataPending();
+
+ // Trace message
+ //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('NETWORK-PACKAGE: hasArrived=%d - EXIT!', intval($hasArrived)));
+
+ // Return the status
+ return $hasArrived;
+ }
+
+ /**
+ * Handles the incoming decoded raw data. This method does not "convert" the
+ * decoded data back into a package array, it just "handles" it and pushs it
+ * on the next stack.
+ *
+ * @return void
+ */
+ public function handleIncomingDecodedData () {
+ /*
+ * This method should only be called if decoded raw data is pending,
+ * so check it again.
+ */
+ if (!$this->isRawDataPending()) {
+ // This is not fatal but should be avoided
+ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('NETWORK-PACKAGE: No raw (decoded?) data is pending, but ' . __METHOD__ . ' has been called!');
+ return;
+ } // END - if
+
+ // Very noisy debug message:
+ //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('NETWORK-PACKAGE: Stacker size is ' . $this->getStackInstance()->getStackCount(self::STACKER_NAME_DECODED_INCOMING) . ' entries.');
+
+ // "Pop" the next entry (the same array again) from the stack
+ $packageInstance = $this->getStackInstance()->popNamed(self::STACKER_NAME_DECODED_INCOMING);
+
+ /*
+ * Also make sure the error code is SOCKET_ERROR_UNHANDLED because we
+ * only want to handle unhandled packages here.
+ */
+ // Remove the last chunk SEPARATOR (because there is no need for it)
+ //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('NETWORK-PACKAGE: errorCode=' . $packageInstance->getErrorCode() . '(' . StorableSocket::SOCKET_ERROR_UNHANDLED . ')');
+ if (substr($packageInstance->getRawData(), -1, 1) == PackageFragmenter::CHUNK_SEPARATOR) {
+ // It is there and should be removed
+ $packageInstance->getRawData() = substr($packageInstance->getRawData(), 0, -1);
+ } // END - if
+
+ // This package is "handled" and can be pushed on the next stack
+ //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('NETWORK-PACKAGE: Pushing ' . strlen($packageInstance->getRawData()) . ' bytes to stack ' . self::STACKER_NAME_DECODED_HANDLED . ' ...');
+ $this->getStackInstance()->pushNamed(self::STACKER_NAME_DECODED_HANDLED, $packageInstance);
+ }
+
+ /**
+ * Adds raw decoded data from the given handler instance to this receiver
+ *
+ * @param $handlerInstance An instance of a Networkable class
+ * @return void
+ */
+ public function addRawDataToIncomingStack (Networkable $handlerInstance) {
+ /*
+ * Get the decoded data from the handler, this is an array with
+ * 'raw_data' and 'error_code' as elements.
+ */
+ $packageInstance = $handlerInstance->getNextRawData();
+
+ // Very noisy debug message:
+ //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('NETWORK-PACKAGE: decodedData[' . gettype($packageInstance) . ']=' . print_r($packageInstance, TRUE));
+
+ // And push it on our stack
+ $this->getStackInstance()->pushNamed(self::STACKER_NAME_DECODED_INCOMING, $packageInstance);
+ }
+
+ /**
+ * Checks whether incoming decoded data is handled.
+ *
+ * @return $isHandled Whether incoming decoded data is handled
+ */
+ public function isIncomingRawDataHandled () {
+ // Determine if the stack is not empty
+ $isHandled = (!$this->getStackInstance()->isStackEmpty(self::STACKER_NAME_DECODED_HANDLED));
+
+ // Return it
+ return $isHandled;
+ }
+
+ /**
+ * Checks whether the assembler has pending data left
+ *
+ * @return $isHandled Whether the assembler has pending data left
+ */
+ public function ifAssemblerHasPendingDataLeft () {
+ // Determine if the stack is not empty
+ $isHandled = (!$this->getAssemblerInstance()->isPendingDataEmpty());
+
+ // Return it
+ return $isHandled;
+ }
+
+ /**
+ * Checks whether the assembler has multiple packages pending
+ *
+ * @return $isPending Whether the assembler has multiple packages pending
+ */
+ public function ifMultipleMessagesPending () {
+ // Determine if the stack is not empty
+ $isPending = ($this->getAssemblerInstance()->ifMultipleMessagesPending());
+
+ // Return it
+ return $isPending;
+ }
+
+ /**
+ * Handles the attached assemler's pending data queue to be finally
+ * assembled to the raw package data back.
+ *
+ * @return void
+ */
+ public function handleAssemblerPendingData () {
+ // Debug message
+ //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('NETWORK-PACKAGE: Calling this->getAssemblerInstance()->handlePendingData() ...');
+
+ // Handle it
+ $this->getAssemblerInstance()->handlePendingData();
+ }
+
+ /**
+ * Handles multiple messages.
+ *
+ * @return void
+ */
+ public function handleMultipleMessages () {
+ // Debug message
+ //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('NETWORK-PACKAGE: Calling this->getAssemblerInstance()->handleMultipleMessages() ...');
+
+ // Handle it
+ $this->getAssemblerInstance()->handleMultipleMessages();
+ }
+
+ /**
+ * Assembles incoming decoded data so it will become an abstract network
+ * package again. The assembler does later do it's job by an other task,
+ * not this one to keep best speed possible.
+ *
+ * @return void
+ */
+ public function assembleDecodedDataToPackage () {
+ // Make sure the raw decoded package data is handled
+ assert($this->isIncomingRawDataHandled());
+
+ // Get current package content (an array with two elements; see handleIncomingDecodedData() for details)
+ $packageContent = $this->getStackInstance()->getNamed(self::STACKER_NAME_DECODED_HANDLED);
+
+ // Assert on some elements
+ assert(
+ (is_array($packageContent)) &&
+ (isset($packageContent[HandleableRawData::PACKAGE_RAW_DATA])) &&
+ (isset($packageContent[HandleableRawData::PACKAGE_ERROR_CODE]))
+ );
+
+ // Start assembling the raw package data array by chunking it
+ $this->getAssemblerInstance()->chunkPackageContent($packageContent);
+
+ // Remove the package from 'handled_decoded' stack ...
+ $this->getStackInstance()->popNamed(self::STACKER_NAME_DECODED_HANDLED);
+
+ // ... and push it on the 'chunked' stacker
+ //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('NETWORK-PACKAGE: Pushing ' . strlen($packageContent[HandleableRawData::PACKAGE_RAW_DATA]) . ' bytes on stack ' . self::STACKER_NAME_DECODED_CHUNKED . ',packageContent=' . print_r($packageContent, TRUE));
+ $this->getStackInstance()->pushNamed(self::STACKER_NAME_DECODED_CHUNKED, $packageContent);
+ }
+
+ /**
+ * Accepts the visitor to process the visit "request"
+ *
+ * @param $visitorInstance An instance of a Visitor class
+ * @return void
+ */
+ public function accept (Visitor $visitorInstance) {
+ // Debug message
+ //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('NETWORK-PACKAGE: ' . $visitorInstance->__toString() . ' has visited - CALLED!');
+
+ // Visit the package
+ $visitorInstance->visitNetworkPackageHandler($this);
+
+ // Then visit the assembler to handle multiple packages
+ $this->getAssemblerInstance()->accept($visitorInstance);
+
+ // Debug message
+ //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('NETWORK-PACKAGE: ' . $visitorInstance->__toString() . ' has visited - EXIT!');
+ }
+
+ /**
+ * Clears all stacks
+ *
+ * @return void
+ */
+ public function clearAllStacks () {
+ // Call the init method to force re-initialization
+ $this->initStacks(TRUE);
+
+ // Debug message
+ //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('NETWORK-PACKAGE: All stacker have been re-initialized.');
+ }
+
+ /**
+ * Removes the first failed outoging package from the stack to continue
+ * with next one (it will never work until the issue is fixed by you).
+ *
+ * @return void
+ * @throws UnexpectedPackageStatusException If the package status is not 'failed'
+ * @todo This may be enchanced for outgoing packages?
+ */
+ public function removeFirstFailedPackage () {
+ // Get the package again
+ $packageInstance = $this->getStackInstance()->getNamed(self::STACKER_NAME_DECLARED);
+
+ // Is the package status 'failed'?
+ if ($packageInstance->getStatus() != self::PACKAGE_STATUS_FAILED) {
+ // Not failed!
+ throw new UnexpectedPackageStatusException(array($this, $packageInstance, self::PACKAGE_STATUS_FAILED), self::EXCEPTION_UNEXPECTED_PACKAGE_STATUS);
+ } // END - if
+
+ // Remove this entry
+ $this->getStackInstance()->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 $packageInstance An instance of a DeliverablePackage class
+ */
+ public function decodeRawContent ($rawPackageContent) {
+ // Use the separator '#' to "decode" it
+ $decodedArray = explode(self::PACKAGE_DATA_SEPARATOR, $rawPackageContent);
+
+ // Debug message
+ //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('NETWORK-PACKAGE: decodedArray=' . print_r($decodedArray, TRUE));
+
+ // Assert on count (should be always 3)
+ assert(count($decodedArray) == self::DECODED_DATA_ARRAY_SIZE);
+
+ // Create package instance
+ $packageInstance = PackageDataFactory::createPackageDataInstance();
+
+ // Set all data
+ $packageInstance->setSenderAddress($decodedArray[self::INDEX_PACKAGE_SENDER_ADDRESS]);
+ $packageInstance->setSenderPort($decodedArray[self::INDEX_PACKAGE_SENDER_PORT]);
+ $packageInstance->setRecipient($decodedArray[self::INDEX_PACKAGE_RECIPIENT]);
+ $packageInstance->setContent($decodedArray[self::INDEX_PACKAGE_CONTENT]);
+ $packageInstance->setStatus(self::PACKAGE_STATUS_DECODED);
+ $packageInstance->setHash($decodedArray[self::INDEX_PACKAGE_HASH]);
+ $packageInstance->setPrivateKeyHash($decodedArray[self::INDEX_PACKAGE_PRIVATE_KEY_HASH]);
+
+ // And return it
+ return $packageInstance;
+ }
+
+ /**
+ * Handles decoded data for this node by "decoding" the 'content' part of
+ * it. Again this method uses explode() for the "decoding" process.
+ *
+ * @param $packageInstance An instance of a DeliverablePackage class
+ * @return void
+ * @throws InvalidDataChecksumException If the checksum doesn't match
+ */
+ public function handleRawData (DeliverablePackage $packageInstance) {
+ /*
+ * "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, $packageInstance->getContent());
+
+ // 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. This is much
+ * better to remember than plain numbers, isn't it?
+ */
+ $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 but still compressed
+ 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],
+ // Sender's id
+ self::PACKAGE_CONTENT_SENDER => $packageInstance->getSenderAddress(),
+ // Hash from decoded raw data
+ self::PACKAGE_CONTENT_HASH => $packageInstance->getHash(),
+ // Hash of private key
+ self::PACKAGE_CONTENT_PRIVATE_KEY_HASH => $packageInstance->getPrivateKeyHash()
+ );
+
+ // Is the checksum valid?
+ if (!$this->isChecksumValid($decodedContent, $packageInstance)) {
+ // Is not the same, so throw an exception here
+ throw new InvalidDataChecksumException(array($this, $decodedContent, $packageInstance), self::EXCEPTION_INVALID_DATA_CHECKSUM);
+ } // END - if
+
+ /*
+ * The checksum is the same, then it can be decompressed safely. The
+ * original message is at this point fully decoded.
+ */
+ $decodedContent[self::PACKAGE_CONTENT_MESSAGE] = $this->getCompressorInstance()->decompressStream($decodedContent[self::PACKAGE_CONTENT_MESSAGE]);
+
+ // And push it on the next stack
+ $this->getStackInstance()->pushNamed(self::STACKER_NAME_NEW_MESSAGE, $decodedContent);
+ }
+
+ /**
+ * Checks whether a new message has arrived
+ *
+ * @return $hasArrived Whether a new message has arrived for processing
+ */
+ public function isNewMessageArrived () {
+ // Determine if the stack is not empty
+ $hasArrived = (!$this->getStackInstance()->isStackEmpty(self::STACKER_NAME_NEW_MESSAGE));
+
+ // Return it
+ return $hasArrived;
+ }
+
+ /**
+ * Handles newly arrived messages
+ *
+ * @return void
+ * @todo Implement verification of all sent tags here?
+ */
+ public function handleNewlyArrivedMessage () {
+ // Make sure there is at least one message
+ assert($this->isNewMessageArrived());
+
+ // Get it from the stacker, it is the full array with the decoded message
+ $decodedContent = $this->getStackInstance()->popNamed(self::STACKER_NAME_NEW_MESSAGE);
+
+ // Generate the hash of comparing it
+ if (!$this->isPackageHashValid($decodedContent)) {
+ // Is not valid, so throw an exception here
+ exit(__METHOD__ . ':INVALID HASH! UNDER CONSTRUCTION!' . chr(10));
+ } // END - if
+
+ // Now get a filter chain back from factory with given tags array
+ $chainInstance = PackageFilterChainFactory::createChainByTagsArray($decodedContent[self::PACKAGE_CONTENT_TAGS]);
+
+ /*
+ * Process the message through all filters, note that all other
+ * elements from $decodedContent are no longer needed.
+ */
+ $chainInstance->processMessage($decodedContent, $this);
+
+ /*
+ * Post-processing of message data (this won't remove the message from
+ * the stack).
+ */
+ $chainInstance->postProcessMessage($this);
+ }
+
+ /**
+ * Checks whether a processed message is pending for "interpretation"
+ *
+ * @return $isPending Whether a processed message is pending
+ */
+ public function isProcessedMessagePending () {
+ // Check it
+ $isPending = (!$this->getStackInstance()->isStackEmpty(self::STACKER_NAME_PROCESSED_MESSAGE));
+
+ // Return it
+ return $isPending;
+ }
+
+ /**
+ * Handle processed messages by "interpreting" the 'message_type' element
+ *
+ * @return void
+ */
+ public function handleProcessedMessage () {
+ // Get it from the stacker, it is the full array with the processed message
+ $messageArray = $this->getStackInstance()->popNamed(self::STACKER_NAME_PROCESSED_MESSAGE);
+
+ // Add type for later easier handling
+ $messageArray[self::MESSAGE_ARRAY_DATA][self::MESSAGE_ARRAY_TYPE] = $messageArray[self::MESSAGE_ARRAY_TYPE];
+
+ // Debug message
+ //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('NETWORK-PACKAGE: messageArray=' . print_r($messageArray, TRUE));
+
+ // Create a handler instance from given message type
+ $handlerInstance = MessageTypeHandlerFactory::createMessageTypeHandlerInstance($messageArray[self::MESSAGE_ARRAY_TYPE]);
+
+ // Handle message data
+ $handlerInstance->handleMessageData($messageArray[self::MESSAGE_ARRAY_DATA], $this);
+
+ // Post-handling of message data
+ $handlerInstance->postHandleMessageData($messageArray, $this);
+ }
+
+ /**
+ * Feeds the hash and sender (as recipient for the 'sender' reward) to the
+ * miner's queue, unless the message is not a "reward claim" message as this
+ * leads to an endless loop. You may wish to run the miner to get some
+ * reward ("Hubcoins") for "mining" this hash.
+ *
+ * @param $messageData Array with message data
+ * @return void
+ * @todo ~10% done?
+ */
+ public function feedHashToMiner (array $messageData) {
+ // Debug message
+ //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('NETWORK-PACKAGE: messageData()=%d - CALLED!', count($messageData)));
+
+ // Is the feature enabled?
+ if (!FrameworkFeature::isFeatureAvailable('hubcoin_reward')) {
+ /*
+ * Feature is not enabled, don't feed the hash to the miner as it
+ *may be invalid.
+ */
+ return;
+ } // END - if
+
+ // Make sure the required elements are there
+ assert(isset($messageData[self::MESSAGE_ARRAY_SENDER]));
+ assert(isset($messageData[self::MESSAGE_ARRAY_HASH]));
+ assert(isset($messageData[self::MESSAGE_ARRAY_DATA][self::MESSAGE_ARRAY_DATA_NODE_ID]));
+
+ // Copy node id
+ $messageData[self::MESSAGE_ARRAY_DATA_NODE_ID] = $messageData[self::MESSAGE_ARRAY_DATA][self::MESSAGE_ARRAY_DATA_NODE_ID];
+
+ // Let's get rid of some fields that is not needed by the miner:
+ unset($messageData[self::MESSAGE_ARRAY_TYPE]);
+ unset($messageData[self::MESSAGE_ARRAY_DATA]);
+
+ // Debug message
+ //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('NETWORK-PACKAGE: messageData=' . print_r($messageData, TRUE));
+
+ // Resolve session id ('sender' is a session id) into node id
+ $nodeId = HubTools::resolveNodeIdBySessionId($messageData[self::MESSAGE_ARRAY_SENDER]);
+
+ // Is 'claim_reward' the message type?
+ if (in_array(Tagable::TAG_CLAIM_MINING_REWARD, $messageData[self::MESSAGE_ARRAY_TAGS])) {
+ /*
+ * Then don't feed this message to the miner as this causes an
+ * endless loop of mining.
+ */
+ return;
+ } // END - if
+
+ // Also remove tags as the miner don't need this.
+ unset($messageData[self::MESSAGE_ARRAY_TAGS]);
+
+ // Unfinished stuff:
+ $this->partialStub(sprintf('[%s:%d]: @TODO nodeId=%s,messageData=%s', __METHOD__, __LINE__, $nodeId, print_r($messageData, TRUE)));
+ }
+
+}
// Import application-specific stuff
use Org\Shipsimu\Hub\Factory\Network\Locator\UniversalNodeLocatorFactory;
+use Org\Shipsimu\Hub\Handler\Package\NetworkPackageHandler;
use Org\Shipsimu\Hub\Handler\Protocol\BaseProtocolHandler;
use Org\Shipsimu\Hub\Locator\Node\LocateableNode;
use Org\Shipsimu\Hub\Locator\Node\Tools\NodeLocatorUtils;
-use Org\Shipsimu\Hub\Network\Package\NetworkPackage;
+use Org\Shipsimu\Hub\Network\Package\DeliverablePackage;
/**
* A general handler for IPv4 protocols such as TCP, UDP and others.
* @param $packageData Valid raw package data
* @return $isValid Whether the UNL can be validated
*/
- public function isValidUniversalNodeLocatorByPackageData (array $packageData) {
+ public function isValidUniversalNodeLocatorByPackageData (DeliverablePackage $packageInstance) {
// Debug message
//* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('IPV4-PROTOCOL-HANDLER: CALLED!');
- // Is 'recipient' there?
- assert(isset($packageData[NetworkPackage::PACKAGE_DATA_RECIPIENT]));
-
// Is the correct handler choosen?
- assert(substr($packageData[NetworkPackage::PACKAGE_DATA_RECIPIENT], 0, strlen($this->getHandlerName())) != $this->getHandlerName());
+ assert(substr($packageInstance->getRecipient(), 0, strlen($this->getHandlerName())) != $this->getHandlerName());
// Default is from generic validation
- $isValid = NodeLocatorUtils::isValidUniversalNodeLocator($packageData[NetworkPackage::PACKAGE_DATA_RECIPIENT]);
+ $isValid = NodeLocatorUtils::isValidUniversalNodeLocator($packageInstance->getRecipient());
// Debug message
- //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('IPV4-PROTOCOL-HANDLER: PACKAGE_DATA_RECIPIENT=' . $packageData[NetworkPackage::PACKAGE_DATA_RECIPIENT] . ',isValid[' . gettype($isValid) . ']=' . intval($isValid));
+ //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('IPV4-PROTOCOL-HANDLER: packageInstance.recipient=' . $packageInstance->getRecipient() . ',isValid[' . gettype($isValid) . ']=' . intval($isValid));
// If this doesn't fail, continue validating the IP:port combination
if ($isValid === TRUE) {
// ... and validate IP:port, first "parse" the UNL
- $unlInstance = UniversalNodeLocatorFactory::createUnlInstanceFromString($packageData[NetworkPackage::PACKAGE_DATA_RECIPIENT]);
+ $unlInstance = UniversalNodeLocatorFactory::createUnlInstanceFromString($packageInstance->getRecipient());
// Set whole UNL instance
// @TODO don't do this in a isValidFoo() method
use Org\Shipsimu\Hub\Factory\Node\NodeObjectFactory;
use Org\Shipsimu\Hub\Generic\HubInterface;
use Org\Shipsimu\Hub\Handler\BaseHubHandler;
-use Org\Shipsimu\Hub\Network\Package\NetworkPackage;
+use Org\Shipsimu\Hub\Handler\Package\NetworkPackageHandler;
+use Org\Shipsimu\Hub\Network\Package\DeliverablePackage;
// Import framework stuff
use Org\Mxchange\CoreFramework\Factory\ObjectFactory;
* Checks whether the 'recipient' field matches our own an universal node
* locator.
*
- * @param $packageData Raw package data
+ * @param $packageData An instance of a DeliverablePackage class
* @return $matches Whether it matches
* @todo This method will be moved to a better place
*/
- protected function ifRecipientMatchesOwnUniversalNodeLocator (array $packageData) {
+ protected function ifRecipientMatchesOwnUniversalNodeLocator (DeliverablePackage $packageInstance) {
// Trace message
//* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('RAW-DATA-HANDLER: packageData()=%d - CALLED!', strlen($packageData)));
$ownAddress = NodeObjectFactory::createNodeInstance()->determineUniversalNodeLocator();
// Does it match?
- $matches = ($ownAddress === $packageData[NetworkPackage::PACKAGE_DATA_RECIPIENT]);
+ $matches = ($ownAddress === $packageInstance->getRecipient());
// Trace message
//* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('RAW-DATA-HANDLER: matches=%d - EXIT!', intval($matches)));
use Org\Shipsimu\Hub\Factory\Fragmenter\FragmenterFactory;
use Org\Shipsimu\Hub\Factory\Network\NetworkPackageFactory;
use Org\Shipsimu\Hub\Factory\State\Peer\PeerStateFactory;
+use Org\Shipsimu\Hub\Handler\Package\NetworkPackageHandler;
use Org\Shipsimu\Hub\Helper\BaseHubSystemHelper;
-use Org\Shipsimu\Hub\Network\Package\NetworkPackage;
+use Org\Shipsimu\Hub\Network\Package\DeliverablePackage;
// Import framework stuff
use Org\Mxchange\CoreFramework\Factory\ObjectFactory;
$this->setOutputStreamInstance($streamInstance);
// Get package instance from factory
- $packageInstance = NetworkPackageFactory::createNetworkPackageInstance();
+ $packageInstance = NetworkPackageHandlerFactory::createNetworkPackageHandlerInstance();
// ... and set it here
- $this->setPackageInstance($packageInstance);
+ $this->setPackageHandlerInstance($packageInstance);
// Register this connection helper
GenericRegistry::getRegistry()->addInstance('connection', $this);
* 1) Request a chunk from set fragmenter instance
* 2) Finally return the chunk (array) to the caller
*
- * @param $packageData Raw package data array
+ * @param $packageData An instance of a DeliverablePackage class array
* @return $chunkData Raw data chunk
*/
- private function getRawDataFromPackageArray (array $packageData) {
+ private function getRawDataFromPackageArray (DeliverablePackage $packageInstance) {
// Debug message
//* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('CONNECTION-HELPER: currentFinalHash=' . $this->currentFinalHash);
}
/**
- * Sends raw package data to the recipient
+ * Sends An instance of a DeliverablePackage class to the recipient
*
- * @param $packageData Raw package data
+ * @param $packageData An instance of a DeliverablePackage class
* @return void
*/
- public function sendRawPackageData (array $packageData) {
+ public function sendRawPackageData (DeliverablePackage $packageInstance) {
// Trace message
//* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('CONNECTION-HELPER: packageData()=%d - CALLED!', count($packageData)));
// Init array
$encodedDataArray = array(
- NetworkPackage::RAW_INDEX_FINAL_HASH => $this->currentFinalHash,
- NetworkPackage::RAW_INDEX_ENCODED_DATA => $encodedData,
- NetworkPackage::RAW_INDEX_SENT_BYTES => 0,
- NetworkPackage::RAW_INDEX_SOCKET_INSTANCE => $this->getSocketInstance(),
- NetworkPackage::RAW_INDEX_BUFFER_SIZE => $bufferSize,
- NetworkPackage::RAW_INDEX_DIFF => ($bufferSize - strlen($encodedData)),
+ NetworkPackageHandler::RAW_INDEX_FINAL_HASH => $this->currentFinalHash,
+ NetworkPackageHandler::RAW_INDEX_ENCODED_DATA => $encodedData,
+ NetworkPackageHandler::RAW_INDEX_SENT_BYTES => 0,
+ NetworkPackageHandler::RAW_INDEX_SOCKET_INSTANCE => $this->getSocketInstance(),
+ NetworkPackageHandler::RAW_INDEX_BUFFER_SIZE => $bufferSize,
+ NetworkPackageHandler::RAW_INDEX_DIFF => ($bufferSize - strlen($encodedData)),
);
// Push raw data to the package's outgoing stack
- $this->getPackageInstance()->getStackInstance()->pushNamed(NetworkPackage::STACKER_NAME_OUTGOING_STREAM, $encodedDataArray);
+ $this->getPackageHandlerInstance()->getStackInstance()->pushNamed(NetworkPackageHandler::STACKER_NAME_OUTGOING_STREAM, $encodedDataArray);
// Trace message
//* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('CONNECTION-HELPER: EXIT!');
use Org\Shipsimu\Hub\Container\Socket\StorableSocket;
use Org\Shipsimu\Hub\Factory\Handler\Protocol\ProtocolHandlerFactory;
use Org\Shipsimu\Hub\Factory\Socket\SocketFactory;
+use Org\Shipsimu\Hub\Handler\Package\NetworkPackageHandler;
use Org\Shipsimu\Hub\Helper\Connection\ConnectionHelper;
use Org\Shipsimu\Hub\Helper\Connection\Network\IpV4\BaseIpV4ConnectionHelper;
use Org\Shipsimu\Hub\Locator\Node\LocateableNode;
-use Org\Shipsimu\Hub\Network\Package\NetworkPackage;
+use Org\Shipsimu\Hub\Network\Package\DeliverablePackage;
use Org\Shipsimu\Hub\Tools\HubTools;
// Import framework stuff
* recipient in package data. After you called this method you still need to
* connect to the other node.
*
- * @param $packageData Raw package data
+ * @param $packageData An instance of a DeliverablePackage class
* @return $socketInstance An instance of a StorableSocket class
*/
- public static function createConnectionFromPackageData (array $packageData) {
+ public static function createConnectionFromPackageInstance (DeliverablePackage $packageInstance) {
// Create an instance
$helperInstance = new TcpConnectionHelper();
// Construct container class, this won't be reached if an exception is thrown
- $socketInstance = SocketFactory::createTcpOutgoingSocketFromPackageData($packageData);
+ $socketInstance = SocketFactory::createTcpOutgoingSocketFromPackageInstance($packageData);
// Set the resource
$helperInstance->setSocketInstance($socketInstance);
// Try to solve the recipient
try {
// Get protocol handler back from package data
- $handlerInstance = ProtocolHandlerFactory::createProtocolHandlerFromPackageData($packageData);
+ $handlerInstance = ProtocolHandlerFactory::createProtocolHandlerFromPackageInstance($packageData);
// Get UNL instance
$unlInstance = $handlerInstance->getUniversalNodeLocatorInstance();
$helperInstance->setHandlerInstance($handlerInstance);
} catch (NoValidHostnameException $e) {
// Debug message
- self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('CONNECTION-HELPER: Failed to resolve ' . $packageData[NetworkPackage::PACKAGE_DATA_RECIPIENT] . ':' . $e->getMessage());
+ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('CONNECTION-HELPER: Failed to resolve ' . $packageInstance->getRecipient() . ':' . $e->getMessage());
// Is the recipient equal as configured UNL?
- if (substr($packageData[NetworkPackage::PACKAGE_DATA_RECIPIENT], 0, strlen($helperInstance->getConfigInstance()->getConfigEntry('external_address'))) == $helperInstance->getConfigInstance()->getConfigEntry('external_address')) {
+ if (substr($packageInstance->getRecipient(), 0, strlen($helperInstance->getConfigInstance()->getConfigEntry('external_address'))) == $helperInstance->getConfigInstance()->getConfigEntry('external_address')) {
// This may connect to shipsimu.org and requests 'ip.php' which will return our external IP address
$unlAddress = HubTools::determineExternalAddress();
// Do we have ip:port match?
// @TODO Rewrite this test for UNLs
- if (strpos($packageData[NetworkPackage::PACKAGE_DATA_RECIPIENT], ':') === FALSE) {
+ if (strpos($packageInstance->getRecipient(), ':') === FALSE) {
// No ip:port!
- $helperInstance->debugInstance(sprintf('[%s:%d]: recipient=%s does not contain ":". Please fix this.', __METHOD__, __LINE__, $packageData[NetworkPackage::PACKAGE_DATA_RECIPIENT]));
+ $helperInstance->debugInstance(sprintf('[%s:%d]: recipient=%s does not contain ":". Please fix this.', __METHOD__, __LINE__, $packageInstance->getRecipient()));
} // END - if
// "explode" the ip:port, so index 1 will be the port number
// @TODO Rewrite this test for UNLs
- $recipientArray = explode(':', $packageData[NetworkPackage::PACKAGE_DATA_RECIPIENT]);
+ $recipientArray = explode(':', $packageInstance->getRecipient());
// Add the port
$unlPort = $recipientArray[LocateableNode::UNL_PART_PORT];
//$unlInstance =;
} else {
// It doesn't match, we need to take care of this later
- $helperInstance->debugInstance(sprintf('[%s:%d]: recipient=%s!=%s', __METHOD__, __LINE__, $packageData[NetworkPackage::PACKAGE_DATA_RECIPIENT], $helperInstance->getConfigInstance()->getConfigEntry('external_address')));
+ $helperInstance->debugInstance(sprintf('[%s:%d]: recipient=%s!=%s', __METHOD__, __LINE__, $packageInstance->getRecipient(), $helperInstance->getConfigInstance()->getConfigEntry('external_address')));
}
}
use Org\Shipsimu\Hub\Container\Socket\StorableSocket;
use Org\Shipsimu\Hub\Helper\Connection\ConnectionHelper;
use Org\Shipsimu\Hub\Helper\Connection\Network\IpV4\BaseIpV4ConnectionHelper;
+use Org\Shipsimu\Hub\Network\Package\DeliverablePackage;
/**
* A UDP connection helper class
* recipient in package data. After you called this method you still need to
* connect to the other node.
*
- * @param $packageData Raw package data
+ * @param $packageData An instance of a DeliverablePackage class
* @return $socketInstance An instance of a StorableSocket class
*/
- public static function createConnectionFromPackageData (array $packageData) {
+ public static function createConnectionFromPackageInstance (DeliverablePackage $packageInstance) {
$this->debugBackTrace(': Unfinished method, packageData[]=' . count($packageData));
}
use Org\Shipsimu\Hub\Dht\Distributable;
use Org\Shipsimu\Hub\Factory\Network\NetworkPackageFactory;
use Org\Shipsimu\Hub\Generic\BaseHubSystem;
+use Org\Shipsimu\Hub\Handler\Package\NetworkPackageHandler;
use Org\Shipsimu\Hub\Helper\BaseHubSystemHelper;
use Org\Shipsimu\Hub\Helper\Dht\HelpableDht;
-use Org\Shipsimu\Hub\Network\Package\NetworkPackage;
// Import framework stuff
use Org\Mxchange\CoreFramework\Factory\Template\XmlTemplateEngineFactory;
parent::__construct(__CLASS__);
// Set recipient type
- $this->setRecipientType(NetworkPackage::NETWORK_TARGET_DHT);
+ $this->setRecipientType(NetworkPackageHandler::NETWORK_TARGET_DHT);
// Set package tags
$this->setPackageTags(array('dht_bootstrap'));
$this->getTemplateInstance()->compileTemplate();
// Get a singleton network package instance
- $packageInstance = NetworkPackageFactory::createNetworkPackageInstance();
+ $packageInstance = NetworkPackageHandlerFactory::createNetworkPackageHandlerInstance();
// Next, feed the content in. The network package class is a pipe-through class.
//* DEBUG: */ die(__METHOD__ . ':dhtInstance=' . print_r($dhtInstance, TRUE));
use Org\Shipsimu\Hub\Dht\Distributable;
use Org\Shipsimu\Hub\Factory\Network\NetworkPackageFactory;
use Org\Shipsimu\Hub\Generic\BaseHubSystem;
+use Org\Shipsimu\Hub\Handler\Package\NetworkPackageHandler;
use Org\Shipsimu\Hub\Helper\BaseHubSystemHelper;
use Org\Shipsimu\Hub\Helper\Dht\HelpableDht;
-use Org\Shipsimu\Hub\Network\Package\NetworkPackage;
// Import framework stuff
use Org\Mxchange\CoreFramework\Factory\Template\XmlTemplateEngineFactory;
parent::__construct(__CLASS__);
// Set recipient type
- $this->setRecipientType(NetworkPackage::NETWORK_TARGET_DHT);
+ $this->setRecipientType(NetworkPackageHandler::NETWORK_TARGET_DHT);
// Set package tags
$this->setPackageTags(array('dht_publish_entry'));
$this->getTemplateInstance()->compileTemplate();
// Get a singleton network package instance
- $packageInstance = NetworkPackageFactory::createNetworkPackageInstance();
+ $packageInstance = NetworkPackageHandlerFactory::createNetworkPackageHandlerInstance();
// Next, feed the content in. The network package class is a pipe-through class.
$packageInstance->enqueueRawDataFromTemplate($this);
// Import application-specific stuff
use Org\Shipsimu\Hub\Factory\Network\NetworkPackageFactory;
+use Org\Shipsimu\Hub\Handler\Package\NetworkPackageHandler;
use Org\Shipsimu\Hub\Helper\Node\BaseNodeHelper;
use Org\Shipsimu\Hub\Helper\Node\HelpableNode;
-use Org\Shipsimu\Hub\Network\Package\NetworkPackage;
use Org\Shipsimu\Hub\Node\Node;
// Import framework stuff
parent::__construct(__CLASS__);
// Set recipient type
- $this->setRecipientType(NetworkPackage::NETWORK_TARGET_UPPER);
+ $this->setRecipientType(NetworkPackageHandler::NETWORK_TARGET_UPPER);
// Set package tags
$this->setPackageTags(array('announcement'));
$this->getTemplateInstance()->compileTemplate();
// Get a singleton network package instance
- $packageInstance = NetworkPackageFactory::createNetworkPackageInstance();
+ $packageInstance = NetworkPackageHandlerFactory::createNetworkPackageHandlerInstance();
// Next, feed the content in. The network package class is a pipe-through class.
$packageInstance->enqueueRawDataFromTemplate($this);
$this->getTemplateInstance()->compileTemplate();
// Get a singleton network package instance
- $packageInstance = NetworkPackageFactory::createNetworkPackageInstance();
+ $packageInstance = NetworkPackageHandlerFactory::createNetworkPackageHandlerInstance();
// Next, feed the content in. The network package class is a pipe-through class.
$packageInstance->enqueueRawDataFromTemplate($this);
$this->getTemplateInstance()->compileTemplate();
// Get a singleton network package instance
- $packageInstance = NetworkPackageFactory::createNetworkPackageInstance();
+ $packageInstance = NetworkPackageHandlerFactory::createNetworkPackageHandlerInstance();
// Next, feed the content in. The network package class is a pipe-through class.
$packageInstance->enqueueRawDataFromTemplate($this);
$this->getTemplateInstance()->compileTemplate();
// Get a singleton network package instance
- $packageInstance = NetworkPackageFactory::createNetworkPackageInstance();
+ $packageInstance = NetworkPackageHandlerFactory::createNetworkPackageHandlerInstance();
// Next, feed the content in. The network package class is a pipe-through class.
$packageInstance->enqueueRawDataFromTemplate($this);
// Import application-specific stuff
use Org\Shipsimu\Hub\Factory\Network\NetworkPackageFactory;
+use Org\Shipsimu\Hub\Handler\Package\NetworkPackageHandler;
use Org\Shipsimu\Hub\Helper\Node\BaseNodeHelper;
use Org\Shipsimu\Hub\Helper\Node\HelpableNode;
-use Org\Shipsimu\Hub\Network\Package\NetworkPackage;
use Org\Shipsimu\Hub\Node\Node;
use Org\Shipsimu\Hub\Tag\Tagable;
parent::__construct(__CLASS__);
// Set recipient type
- $this->setRecipientType(NetworkPackage::NETWORK_TARGET_SELF);
+ $this->setRecipientType(NetworkPackageHandler::NETWORK_TARGET_SELF);
// Set package tags
$this->setPackageTags(array(Tagable::TAG_SELF_CONNECT));
$this->getTemplateInstance()->compileTemplate();
// Get a singleton network package instance
- $packageInstance = NetworkPackageFactory::createNetworkPackageInstance();
+ $packageInstance = NetworkPackageHandlerFactory::createNetworkPackageHandlerInstance();
// Next, feed the content in. The network package class is a pipe-through class.
$packageInstance->enqueueRawDataFromTemplate($this);
// Import application-specific stuff
use Org\Shipsimu\Hub\Factory\Network\NetworkPackageFactory;
+use Org\Shipsimu\Hub\Handler\Package\NetworkPackageHandler;
use Org\Shipsimu\Hub\Helper\Node\BaseNodeHelper;
use Org\Shipsimu\Hub\Helper\Node\HelpableNode;
-use Org\Shipsimu\Hub\Network\Package\NetworkPackage;
use Org\Shipsimu\Hub\Node\Node;
// Import framework stuff
parent::__construct(__CLASS__);
// Set recipient type
- $this->setRecipientType(NetworkPackage::NETWORK_TARGET_UPPER);
+ $this->setRecipientType(NetworkPackageHandler::NETWORK_TARGET_UPPER);
// Set package tags
$this->setPackageTags(array('request_node_list'));
$this->getTemplateInstance()->compileTemplate();
// Get a singleton network package instance
- $packageInstance = NetworkPackageFactory::createNetworkPackageInstance();
+ $packageInstance = NetworkPackageHandlerFactory::createNetworkPackageHandlerInstance();
// Next, feed the content in. The network package class is a pipe-through class.
$packageInstance->enqueueRawDataFromTemplate($this);
use Org\Shipsimu\Hub\Factory\Node\NodeObjectFactory;
use Org\Shipsimu\Hub\Factory\Socket\SocketFactory;
use Org\Shipsimu\Hub\Generic\BaseHubSystem;
+use Org\Shipsimu\Hub\Handler\Package\NetworkPackageHandler;
use Org\Shipsimu\Hub\Information\ShareableInfo;
-use Org\Shipsimu\Hub\Network\Package\NetworkPackage;
+use Org\Shipsimu\Hub\Network\Package\DeliverablePackage;
use Org\Shipsimu\Hub\Pool\Peer\PoolablePeer;
use Org\Shipsimu\Hub\Pool\Poolable;
// Debugging:
//* DEBUG-DIE: */ $infoInstance->debugInstance();
- // Create a faked package data array
- $packageData = array(
- NetworkPackage::PACKAGE_DATA_SENDER_ADDRESS => $peerAddress . $peerSuffix,
- NetworkPackage::PACKAGE_DATA_SENDER_PORT => $peerPort,
- NetworkPackage::PACKAGE_DATA_RECIPIENT => $nodeInstance->getSessionId(),
- NetworkPackage::PACKAGE_DATA_STATUS => NetworkPackage::PACKAGE_STATUS_FAKED
- );
+ // Create a faked package data instance
+ $packageInstance = DeliverPackageFactory::createDeliverPackageInstance();
+
+ // Set all required data
+ $packageInstance->setSenderAddres($peerAddress . $peerSuffix);
+ $packageInstance->setSenderPort($peerPort);
+ $packageInstance->setRecipient($nodeInstance->getSessionId());
+ $packageInstance->setStatus(NetworkPackageHandler::PACKAGE_STATUS_FAKED);
+ die(__METHOD__.': UNFINISHED!');
// Register the socket with the registry and with the faked array
- $this->getRegistryInstance()->registerSocketInstance($infoInstance, $socketInstance, $packageData);
+ $this->getRegistryInstance()->registerSocketInstance($infoInstance, $socketInstance);
// Trace message
//* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('%s-LISTENER: Calling this.handlerInstance.processRawDataFromSocketInstance(resource=%s) ...', strtoupper($this->getProtocolName()), $socketInstance->getSocketResource()));
/**
* Checks whether the listener would accept the given package data array
*
- * @param $packageData Raw package data
+ * @param $packageData An instance of a DeliverablePackage class
* @return $accepts Whether this listener does accept
*/
- public function ifListenerAcceptsPackageData (array $packageData) {
+ public function ifListenerAcceptsPackageData (DeliverablePackage $packageInstance) {
// Trace message
//* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('%s-LISTENER: packageData()=%d - CALLED!', strtoupper($this->getProtocolName()), count($packageData)));
$socketProtocol = $this->getSocketInstance()->getSocketProtocol();
// Get UNL instance
- $unlInstance = UniversalNodeLocatorFactory::createUnlInstanceFromString($packageData[NetworkPackage::PACKAGE_DATA_RECIPIENT]);
+ $unlInstance = UniversalNodeLocatorFactory::createUnlInstanceFromString($packageInstance->getRecipient());
// Get protocol from it
$unlProtocol = $unlInstance->getUnlProtocol();
} // END - if
// Get receiver (network package) instance
- $receiverInstance = NetworkPackageFactory::createNetworkPackageInstance();
+ $receiverInstance = NetworkPackageHandlerFactory::createNetworkPackageHandlerInstance();
/*
* There is some decoded data waiting. The receiver instance is an
use Org\Shipsimu\Hub\Factory\Tag\Package\PackageTagsFactory;
use Org\Shipsimu\Hub\Listener\BaseListener;
use Org\Shipsimu\Hub\Listener\Listenable;
+use Org\Shipsimu\Hub\Network\Package\DeliverablePackage;
// Import framework stuff
use Org\Mxchange\CoreFramework\Bootstrap\FrameworkBootstrap;
/**
* Checks whether the listener would accept the given package data array
*
- * @param $packageData Raw package data
+ * @param $packageData An instance of a DeliverablePackage class
* @return $accepts Whether this listener does accept
*/
- public function ifListenerAcceptsPackageData (array $packageData) {
+ public function ifListenerAcceptsPackageData (DeliverablePackage $packageInstance) {
// Trace message
//* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('SOCKET-FILE-LISTENER: packageData()=%d - CALLED!', count($packageData)));
use Org\Shipsimu\Hub\Factory\Tag\Package\PackageTagsFactory;
use Org\Shipsimu\Hub\Listener\BaseListenerDecorator;
use Org\Shipsimu\Hub\Listener\Listenable;
+use Org\Shipsimu\Hub\Network\Package\DeliverablePackage;
// Import framework stuff
/**
* Checks whether the listener would accept the given package data array
*
- * @param $packageData Raw package data
+ * @param $packageData An instance of a DeliverablePackage class
* @return $accepts Whether this listener does accept
*/
- public function ifListenerAcceptsPackageData (array $packageData) {
+ public function ifListenerAcceptsPackageData (DeliverablePackage $packageInstance) {
// Debug message
/* NOSY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('SOCKET-FILE-LISTENER: Calling this->getListenerInstance()->ifListenerAcceptsPackageData() ...');
use Org\Shipsimu\Hub\Factory\Tag\Package\PackageTagsFactory;
use Org\Shipsimu\Hub\Listener\BaseListenerDecorator;
use Org\Shipsimu\Hub\Listener\Listenable;
+use Org\Shipsimu\Hub\Network\Package\DeliverablePackage;
// Import framework stuff
/**
* Checks whether the listener would accept the given package data array
*
- * @param $packageData Raw package data
+ * @param $packageData An instance of a DeliverablePackage class
* @return $accepts Whether this listener does accept
*/
- public function ifListenerAcceptsPackageData (array $packageData) {
+ public function ifListenerAcceptsPackageData (DeliverablePackage $packageInstance) {
// Trace message
/* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('CLIENT-TCP-LISTENER: packageData()=%d - CALLED!', count($packageData)));
use Org\Shipsimu\Hub\Factory\Tag\Package\PackageTagsFactory;
use Org\Shipsimu\Hub\Listener\BaseListenerDecorator;
use Org\Shipsimu\Hub\Listener\Listenable;
+use Org\Shipsimu\Hub\Network\Package\DeliverablePackage;
// Import framework stuff
/**
* Checks whether the listener would accept the given package data array
*
- * @param $packageData Raw package data
+ * @param $packageData An instance of a DeliverablePackage class
* @return $accepts Whether this listener does accept
*/
- public function ifListenerAcceptsPackageData (array $packageData) {
+ public function ifListenerAcceptsPackageData (DeliverablePackage $packageInstance) {
// Trace message
/* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('HUB-TCP-LISTENER: packageData()=%d - CALLED!', count($packageData)));
use Org\Shipsimu\Hub\Factory\Socket\SocketFactory;
use Org\Shipsimu\Hub\Listener\BaseListener;
use Org\Shipsimu\Hub\Listener\Listenable;
+use Org\Shipsimu\Hub\Network\Package\DeliverablePackage;
// Import framework stuff
use Org\Mxchange\CoreFramework\Factory\ObjectFactory;
/**
* Checks whether the listener would accept the given package data array
*
- * @param $packageData Raw package data
+ * @param $packageData An instance of a DeliverablePackage class
* @return $accepts Whether this listener does accept
* @throws UnsupportedOperationException If this method is called
*/
- public function ifListenerAcceptsPackageData (array $packageData) {
+ public function ifListenerAcceptsPackageData (DeliverablePackage $packageInstance) {
throw new UnsupportedOperationException(array($this, __FUNCTION__), self::EXCEPTION_UNSPPORTED_OPERATION);
}
use Org\Shipsimu\Hub\Factory\Tag\Package\PackageTagsFactory;
use Org\Shipsimu\Hub\Listener\BaseListenerDecorator;
use Org\Shipsimu\Hub\Listener\Listenable;
+use Org\Shipsimu\Hub\Network\Package\DeliverablePackage;
// Import framework stuff
/**
* Checks whether the listener would accept the given package data array
*
- * @param $packageData Raw package data
+ * @param $packageData An instance of a DeliverablePackage class
* @return $accepts Whether this listener does accept
*/
- function ifListenerAcceptsPackageData (array $packageData) {
+ function ifListenerAcceptsPackageData (DeliverablePackage $packageInstance) {
// Trace message
/* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('CLIENT-UDP-LISTENER: packageData()=%d - CALLED!', count($packageData)));
use Org\Shipsimu\Hub\Factory\Tag\Package\PackageTagsFactory;
use Org\Shipsimu\Hub\Listener\BaseListenerDecorator;
use Org\Shipsimu\Hub\Listener\Listenable;
+use Org\Shipsimu\Hub\Network\Package\DeliverablePackage;
// Import framework stuff
/**
* Checks whether the listener would accept the given package data array
*
- * @param $packageData Raw package data
+ * @param $packageData An instance of a DeliverablePackage class
* @return $accepts Whether this listener does accept
*/
- public function ifListenerAcceptsPackageData (array $packageData) {
+ public function ifListenerAcceptsPackageData (DeliverablePackage $packageInstance) {
// Trace message
/* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('HUB-UDP-LISTENER: packageData()=%d - CALLED!', count($packageData)));
use Org\Shipsimu\Hub\Factory\State\Node\NodeStateFactory;
use Org\Shipsimu\Hub\Locator\Node\LocateableNode;
use Org\Shipsimu\Hub\Generic\BaseHubSystem;
-use Org\Shipsimu\Hub\Network\Package\NetworkPackage;
+use Org\Shipsimu\Hub\Handler\Package\NetworkPackageHandler;
use Org\Shipsimu\Hub\Network\Receive\Receivable;
use Org\Shipsimu\Hub\Template\Engine\Xml\Network\Answer\BaseXmlAnswerTemplateEngine;
use Org\Shipsimu\Hub\Template\Engine\Xml\ObjectRegistry\XmlObjectRegistryTemplateEngine;
assert(!empty($messageData[BaseXmlAnswerTemplateEngine::ANSWER_STATUS]));
// Construct configuration entry for handling class' name
- $classConfigEntry = strtolower($messageData[NetworkPackage::MESSAGE_ARRAY_TYPE] . '_status_' . $messageData[BaseXmlAnswerTemplateEngine::ANSWER_STATUS]) . '_handler_class';
+ $classConfigEntry = strtolower($messageData[NetworkPackageHandler::MESSAGE_ARRAY_TYPE] . '_status_' . $messageData[BaseXmlAnswerTemplateEngine::ANSWER_STATUS]) . '_handler_class';
// Try to get a class
$handlerInstance = ObjectFactory::createObjectByConfiguredName($classConfigEntry);
use Org\Shipsimu\Hub\Factory\Handler\Chunk\ChunkHandlerFactory;
use Org\Shipsimu\Hub\Generic\BaseHubSystem;
use Org\Shipsimu\Hub\Handler\Network\RawData\HandleableRawData;
+use Org\Shipsimu\Hub\Handler\Package\NetworkPackageHandler;
use Org\Shipsimu\Hub\Network\Package\Fragment\PackageFragmenter;
-use Org\Shipsimu\Hub\Network\Package\NetworkPackage;
use Org\Shipsimu\Hub\Network\Receive\Receivable;
// Import framework stuff
$assemblerInstance = new PackageAssembler();
// Set package instance here
- $assemblerInstance->setPackageInstance($packageInstance);
+ $assemblerInstance->setPackageHandlerInstance($packageInstance);
// Create an instance of a raw data input stream
$streamInstance = ObjectFactory::createObjectByConfiguredName('node_raw_data_input_stream_class');
*/
private function ifInputBufferIsEmpty () {
// Check it
- $isInputBufferEmpty = $this->getPackageInstance()->getStackInstance()->isStackEmpty(NetworkPackage::STACKER_NAME_DECODED_HANDLED);
+ $isInputBufferEmpty = $this->getPackageHandlerInstance()->getStackInstance()->isStackEmpty(NetworkPackageHandler::STACKER_NAME_DECODED_HANDLED);
// Debug message
//* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('PACKAGE-ASSEMBLER: isInputBufferEmpty=' . intval($isInputBufferEmpty));
*/
private function handlePackageByUnhandledPackage (array $packageContent) {
// Debug message
- //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('PACKAGE-ASSEMBLER: packageData[' . HandleableRawData::PACKAGE_RAW_DATA . ']=' . $packageContent[HandleableRawData::PACKAGE_RAW_DATA]);
+ //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('PACKAGE-ASSEMBLER: packageContent[' . HandleableRawData::PACKAGE_RAW_DATA . ']=' . $packageContent[HandleableRawData::PACKAGE_RAW_DATA]);
// Check for some conditions
if ((!$this->ifInputBufferIsEmpty()) || (!$this->isPackageContentCompleted($packageContent))) {
$this->pendingData = '';
}
}
-
-// [EOF]
-?>
+++ /dev/null
-<?php
-// Own namespace
-namespace Org\Shipsimu\Hub\Network\Package;
-
-// Import application-specific stuff
-use Org\Shipsimu\Hub\Container\Socket\StorableSocket;
-use Org\Shipsimu\Hub\Database\Frontend\Node\Dht\NodeDistributedHashTableDatabaseWrapper;
-use Org\Shipsimu\Hub\Factory\Assembler\Package\PackageAssemblerFactory;
-use Org\Shipsimu\Hub\Factory\Dht\DhtObjectFactory;
-use Org\Shipsimu\Hub\Factory\Discovery\Package\PackageDiscoveryFactory;
-use Org\Shipsimu\Hub\Factory\Discovery\Socket\SocketDiscoveryFactory;
-use Org\Shipsimu\Hub\Factory\FilterChain\Package\PackageFilterChainFactory;
-use Org\Shipsimu\Hub\Factory\Handler\Message\MessageTypeHandlerFactory;
-use Org\Shipsimu\Hub\Factory\Information\Connection\ConnectionInfoFactory;
-use Org\Shipsimu\Hub\Factory\Node\NodeObjectFactory;
-use Org\Shipsimu\Hub\Generic\BaseHubSystem;
-use Org\Shipsimu\Hub\Handler\Network\RawData\HandleableRawData;
-use Org\Shipsimu\Hub\Helper\Connection\ConnectionHelper;
-use Org\Shipsimu\Hub\Helper\HubHelper;
-use Org\Shipsimu\Hub\Information\ShareableInfo;
-use Org\Shipsimu\Hub\Network\Deliver\Deliverable;
-use Org\Shipsimu\Hub\Network\Networkable;
-use Org\Shipsimu\Hub\Network\Package\Fragment\PackageFragmenter;
-use Org\Shipsimu\Hub\Network\Receive\Receivable;
-use Org\Shipsimu\Hub\Node\Generic\InvalidPrivateKeyHashException;
-use Org\Shipsimu\Hub\Tag\Tagable;
-use Org\Shipsimu\Hub\Tools\HubTools;
-
-// Import framework stuff
-use Org\Mxchange\CoreFramework\Compressor\Compressor;
-use Org\Mxchange\CoreFramework\Factory\ObjectFactory;
-use Org\Mxchange\CoreFramework\Factory\Registry\Socket\SocketRegistryFactory;
-use Org\Mxchange\CoreFramework\Feature\FrameworkFeature;
-use Org\Mxchange\CoreFramework\Registry\GenericRegistry;
-use Org\Mxchange\CoreFramework\Registry\Registerable;
-use Org\Mxchange\CoreFramework\Socket\InvalidSocketException;
-use Org\Mxchange\CoreFramework\Visitor\Visitable;
-use Org\Mxchange\CoreFramework\Visitor\Visitor;
-
-// Import SPL stuff
-use \Iterator;
-
-/**
- * A NetworkPackage class. This class implements Deliverable and Receivable
- * because all network packages should be deliverable to other nodes and
- * receivable from other nodes. It further provides methods for reading raw
- * content from template engines and feeding it to the stacker for undeclared
- * packages.
- *
- * The factory method requires you to provide a compressor class (which must
- * implement the Compressor interface). If you don't want any compression (not
- * adviceable due to increased network load), please use the NullCompressor
- * class and encode it with BASE64 for a more error-free transfer over the
- * network.
- *
- * For performance reasons, this class should only be instanciated once and then
- * used as a "pipe-through" class.
- *
- * @author Roland Haeder <webmaster@shipsimu.org>
- * @version 0.0.0
- * @copyright Copyright (c) 2007, 2008 Roland Haeder, 2009 - 2018 Hub Developer Team
- * @license GNU GPL 3.0 or any newer version
- * @link http://www.shipsimu.org
- * @todo Needs to add functionality for handling the object's type
- *
- * 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 NetworkPackage extends BaseHubSystem implements Deliverable, Receivable, Registerable, Visitable {
- /**
- * Package mask for compressing package data:
- * 0: Compressor extension
- * 1: Raw package data
- * 2: Tags, seperated by semicolons, no semicolon is required if only one tag is needed
- * 3: Checksum
- * 0 1 2 3
- */
- const PACKAGE_MASK = '%s%s%s%s%s%s%s';
-
- /**
- * Separator for the above mask
- */
- const PACKAGE_MASK_SEPARATOR = '^';
-
- /**
- * 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 = '_';
-
- /**
- * Array indexes for above mask, start with zero
- */
- const INDEX_COMPRESSOR_EXTENSION = 0;
- const INDEX_PACKAGE_DATA = 1;
- const INDEX_TAGS = 2;
- const INDEX_CHECKSUM = 3;
-
- /**
- * Array indexes for raw package array
- */
- const INDEX_PACKAGE_SENDER_ADDRESS = 0;
- const INDEX_PACKAGE_SENDER_PORT = 1;
- const INDEX_PACKAGE_RECIPIENT = 2;
- const INDEX_PACKAGE_CONTENT = 3;
- const INDEX_PACKAGE_STATUS = 4;
- const INDEX_PACKAGE_HASH = 5;
- const INDEX_PACKAGE_PRIVATE_KEY_HASH = 6;
-
- /**
- * Size of the decoded data array
- */
- const DECODED_DATA_ARRAY_SIZE = 6;
-
- /**
- * 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';
- const PACKAGE_CONTENT_SENDER = 'sender';
- const PACKAGE_CONTENT_HASH = 'hash';
- const PACKAGE_CONTENT_PRIVATE_KEY_HASH = 'pkhash';
-
- /**
- * Named array elements for package data
- */
- const PACKAGE_DATA_SENDER_ADDRESS = 'sender_address';
- const PACKAGE_DATA_SENDER_PORT = 'sender_port';
- const PACKAGE_DATA_RECIPIENT = 'recipient';
- const PACKAGE_DATA_CONTENT = 'content';
- const PACKAGE_DATA_STATUS = 'status';
- const PACKAGE_DATA_HASH = 'hash';
- const PACKAGE_DATA_PRIVATE_KEY_HASH = 'pkhash';
-
- /**
- * All package status
- */
- const PACKAGE_STATUS_NEW = 'new';
- const PACKAGE_STATUS_FAILED = 'failed';
- const PACKAGE_STATUS_DECODED = 'decoded';
- const PACKAGE_STATUS_FAKED = 'faked';
-
- /**
- * Constants for message data array
- */
- const MESSAGE_ARRAY_DATA = 'message_data';
- const MESSAGE_ARRAY_TYPE = 'message_type';
- const MESSAGE_ARRAY_SENDER = 'message_sender';
- const MESSAGE_ARRAY_HASH = 'message_hash';
- const MESSAGE_ARRAY_TAGS = 'message_tags';
- const MESSAGE_ARRAY_DATA_NODE_ID = 'node-id';
-
- /**
- * Generic answer status field
- */
-
- /**
- * Tags separator
- */
- const PACKAGE_TAGS_SEPARATOR = ';';
-
- /**
- * Raw package data separator
- */
- const PACKAGE_DATA_SEPARATOR = '#';
-
- /**
- * Separator for more than one recipient
- */
- const PACKAGE_RECIPIENT_SEPARATOR = ':';
-
- /**
- * Network target (alias): 'upper nodes'
- */
- const NETWORK_TARGET_UPPER = 'upper';
-
- /**
- * Network target (alias): 'self'
- */
- const NETWORK_TARGET_SELF = 'self';
-
- /**
- * Network target (alias): 'dht'
- */
- const NETWORK_TARGET_DHT = 'dht';
-
- /**
- * TCP package size in bytes
- */
- const TCP_PACKAGE_SIZE = 512;
-
- /**************************************************************************
- * Stacker for out-going packages *
- **************************************************************************/
-
- /**
- * Stacker name for "undeclared" packages
- */
- const STACKER_NAME_UNDECLARED = 'package_undeclared';
-
- /**
- * Stacker name for "declared" packages (which are ready to send out)
- */
- const STACKER_NAME_DECLARED = 'package_declared';
-
- /**
- * Stacker name for "out-going" packages
- */
- const STACKER_NAME_OUTGOING = 'package_outgoing';
-
- /**************************************************************************
- * Stacker for incoming packages *
- **************************************************************************/
-
- /**
- * Stacker name for "incoming" decoded raw data
- */
- const STACKER_NAME_DECODED_INCOMING = 'package_decoded_data';
-
- /**
- * Stacker name for handled decoded raw data
- */
- const STACKER_NAME_DECODED_HANDLED = 'package_handled_decoded';
-
- /**
- * Stacker name for "chunked" decoded raw data
- */
- const STACKER_NAME_DECODED_CHUNKED = 'package_chunked_decoded';
-
- /**************************************************************************
- * Stacker for incoming messages *
- **************************************************************************/
-
- /**
- * Stacker name for new messages
- */
- const STACKER_NAME_NEW_MESSAGE = 'package_new_message';
-
- /**
- * Stacker name for processed messages
- */
- const STACKER_NAME_PROCESSED_MESSAGE = 'package_processed_message';
-
- /**************************************************************************
- * Stacker for raw data handling *
- **************************************************************************/
-
- /**
- * Stacker for outgoing data stream
- */
- const STACKER_NAME_OUTGOING_STREAM = 'outgoing_stream';
-
- /**
- * Array index for final hash
- */
- const RAW_INDEX_FINAL_HASH = 'hash';
-
- /**
- * Array index for encoded data
- */
- const RAW_INDEX_ENCODED_DATA = 'data';
-
- /**
- * Array index for sent bytes
- */
- const RAW_INDEX_SENT_BYTES = 'sent';
-
- /**
- * Array index for socket resource
- */
- const RAW_INDEX_SOCKET_INSTANCE = 'socket';
-
- /**
- * Array index for buffer size
- */
- const RAW_INDEX_BUFFER_SIZE = 'buffer';
-
- /**
- * Array index for diff between buffer and sent bytes
- */
- const RAW_INDEX_DIFF = 'diff';
-
- /**************************************************************************
- * Protocol names *
- **************************************************************************/
- const PROTOCOL_TCP = 'TCP';
- const PROTOCOL_UDP = 'UDP';
-
- /**************************************************************************
- * Exception codes *
- **************************************************************************/
- const EXCEPTION_UNEXPECTED_PACKAGE_STATUS = 0xff00;
- const EXCEPTION_INVALID_DATA_CHECKSUM = 0xff01;
-
- /**
- * Protected constructor
- *
- * @return void
- */
- protected function __construct () {
- // Call parent constructor
- parent::__construct(__CLASS__);
-
- // The socket needs to be put in a special registry that can handle such data
- $registryInstance = SocketRegistryFactory::createSocketRegistryInstance();
-
- // Set it here
- $this->setRegistryInstance($registryInstance);
- }
-
- /**
- * Creates an instance of this class
- *
- * @param $compressorInstance A Compressor instance for compressing the content
- * @return $packageInstance An instance of a Deliverable class
- */
- public static final function createNetworkPackage (Compressor $compressorInstance) {
- // Get new instance
- $packageInstance = new NetworkPackage();
-
- // Now set the compressor instance
- $packageInstance->setCompressorInstance($compressorInstance);
-
- /*
- * We need to initialize a stack here for our packages even for those
- * which have no recipient address and stamp... ;-) This stacker will
- * also be used for incoming raw data to handle it.
- */
- $stackInstance = ObjectFactory::createObjectByConfiguredName('network_package_stacker_class');
-
- // At last, set it in this class
- $packageInstance->setStackInstance($stackInstance);
-
- // Init all stacker
- $packageInstance->initStacks();
-
- // Get a visitor instance for speeding up things and set it
- $visitorInstance = ObjectFactory::createObjectByConfiguredName('node_raw_data_monitor_visitor_class');
- $packageInstance->setVisitorInstance($visitorInstance);
-
- // Get crypto instance and set it, too
- $cryptoInstance = ObjectFactory::createObjectByConfiguredName('crypto_class');
- $packageInstance->setCryptoInstance($cryptoInstance);
-
- // Get a singleton package assembler instance from factory and set it here, too
- $assemblerInstance = PackageAssemblerFactory::createAssemblerInstance($packageInstance);
- $packageInstance->setAssemblerInstance($assemblerInstance);
-
- // Get node instance
- $nodeInstance = NodeObjectFactory::createNodeInstance();
-
- // Get pool instance from node
- $poolInstance = $nodeInstance->getListenerPoolInstance();
-
- // And set it here
- $packageInstance->setListenerPoolInstance($poolInstance);
-
- // Return the prepared instance
- return $packageInstance;
- }
-
- /**
- * Initialize all stackers
- *
- * @param $forceReInit Whether to force reinitialization of all stacks
- * @return void
- */
- protected function initStacks ($forceReInit = FALSE) {
- // Initialize all
- $this->getStackInstance()->initStacks(array(
- self::STACKER_NAME_UNDECLARED,
- self::STACKER_NAME_DECLARED,
- self::STACKER_NAME_OUTGOING,
- self::STACKER_NAME_DECODED_INCOMING,
- self::STACKER_NAME_DECODED_HANDLED,
- self::STACKER_NAME_DECODED_CHUNKED,
- self::STACKER_NAME_NEW_MESSAGE,
- self::STACKER_NAME_PROCESSED_MESSAGE,
- self::STACKER_NAME_OUTGOING_STREAM
- ), $forceReInit);
- }
-
- /**
- * Determines private key hash from given session id
- *
- * @param $decodedData Array with decoded data
- * @return $hash Private key's hash
- * @throws InvalidPrivateKeyHashException If the private key's hash is not valid
- */
- private function determineSenderPrivateKeyHash (array $decodedData) {
- // Assert on required fields
- assert(!empty($decodedData[self::PACKAGE_CONTENT_SENDER]));
-
- // Get DHT instance
- $dhtInstance = DhtObjectFactory::createDhtInstance('node');
-
- // Ask DHT for session id
- $senderData = $dhtInstance->findNodeLocalBySessionId($decodedData[self::PACKAGE_CONTENT_SENDER]);
-
- // Debugging:
- //* DEBUG-DIE: */ die(sprintf('[%s:%d]: senderData=%s', __METHOD__, __LINE__, print_r($senderData, TRUE)));
-
- // Is an entry found?
- if (count($senderData) > 0) {
- // Make sure the element 'private_key_hash' is there
- //* NOISY-DEBUG */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('NETWORK-PACKAGE: senderData=' . print_r($senderData, TRUE));
- assert(isset($senderData[NodeDistributedHashTableDatabaseWrapper::DB_COLUMN_PRIVATE_KEY_HASH]));
-
- // Don't accept empty hashes
- if (empty($senderData[NodeDistributedHashTableDatabaseWrapper::DB_COLUMN_PRIVATE_KEY_HASH])) {
- // Don't accept
- throw new InvalidPrivateKeyHashException(array($this, $senderData, 'empty hash in senderData'), self::EXCEPTION_INVALID_PRIVATE_KEY_HASH);
- } // END - if
-
- // Return it
- return $senderData[NodeDistributedHashTableDatabaseWrapper::DB_COLUMN_PRIVATE_KEY_HASH];
- } // END - if
-
- // Make sure the requested element is there
- //* DEBUG-DIE */ die('decodedData=' . print_r($decodedData, TRUE));
- assert(isset($decodedData[self::PACKAGE_CONTENT_PRIVATE_KEY_HASH]));
-
- // Don't accept empty keys
- if (empty($decodedData[self::PACKAGE_CONTENT_PRIVATE_KEY_HASH])) {
- // This needs fixing
- throw new InvalidPrivateKeyHashException(array($this, $senderData, 'empty hash in decodedData'), self::EXCEPTION_INVALID_PRIVATE_KEY_HASH);
- } // END - if
-
- // There is no DHT entry so, accept the hash from decoded data
- return $decodedData[self::PACKAGE_CONTENT_PRIVATE_KEY_HASH];
- }
-
- /**
- * "Getter" for hash from given content
- *
- * @param $content Raw package content
- * @return $hash Hash for given package content
- */
- private function getHashFromContent ($content) {
- // Debug message
- //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('NETWORK-PACKAGE: content[md5]=' . md5($content) . ',sender=' . $this->getSessionId() . ',compressor=' . $this->getCompressorInstance()->getCompressorExtension());
-
- // Create the hash
- // @TODO md5() is very weak, but it needs to be fast
- $hash = md5(
- $content .
- self::PACKAGE_CHECKSUM_SEPARATOR .
- $this->getSessionId() .
- self::PACKAGE_CHECKSUM_SEPARATOR .
- $this->getCompressorInstance()->getCompressorExtension()
- );
-
- // Debug message
- //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('NETWORK-PACKAGE: content[md5]=' . md5($content) . ',sender=' . $this->getSessionId() . ',hash=' . $hash . ',compressor=' . $this->getCompressorInstance()->getCompressorExtension());
-
- // And return it
- 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_ADDRESS]);
-
- // Is it the same?
- $isChecksumValid = ($checksum == $decodedContent[self::PACKAGE_CONTENT_CHECKSUM]);
-
- // Return it
- return $isChecksumValid;
- }
-
- /**
- * Change the package with given status in given stack
- *
- * @param $packageData Raw package data in an array
- * @param $stackerName Name of the stacker
- * @param $newStatus New status to set
- * @return void
- */
- private function changePackageStatus (array $packageData, $stackerName, $newStatus) {
- // Skip this for empty stacks
- if ($this->getStackInstance()->isStackEmpty($stackerName)) {
- // This avoids an exception after all packages has failed
- return;
- } // END - if
-
- // Pop the entry (it should be it)
- $nextData = $this->getStackInstance()->popNamed($stackerName);
-
- // Compare both hashes
- assert($nextData[self::PACKAGE_DATA_HASH] == $packageData[self::PACKAGE_DATA_HASH]);
-
- // Temporary set the new status
- $packageData[self::PACKAGE_DATA_STATUS] = $newStatus;
-
- // And push it again
- $this->getStackInstance()->pushNamed($stackerName, $packageData);
- }
-
- /**
- * "Getter" for hash from given content and sender's session id
- *
- * @param $decodedContent Raw 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: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('NETWORK-PACKAGE: content[md5]=' . md5($decodedContent[self::PACKAGE_CONTENT_MESSAGE]) . ',sender=' . $sessionId . ',compressor=' . $decodedContent[self::PACKAGE_CONTENT_EXTENSION]);
-
- // Create the hash
- // @TODO md5() is very weak, but it needs to be fast
- $hash = md5(
- $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
- ///////////////////////////////////////////////////////////////////////////
-
- /**
- * Declares the given raw package data by discovering recipients
- *
- * @param $packageData Raw package data in an array
- * @return void
- */
- private function declareRawPackageData (array $packageData) {
- // Make sure the required field is there
- assert(isset($packageData[self::PACKAGE_DATA_RECIPIENT]));
-
- /*
- * We need to disover every recipient, just in case we have a
- * multi-recipient entry like 'upper' is. 'all' may be a not so good
- * target because it causes an overload on the network and may be
- * abused for attacking the network with large packages.
- */
- $discoveryInstance = PackageDiscoveryFactory::createPackageDiscoveryInstance();
-
- // Discover all recipients, this may throw an exception
- $discoveryInstance->discoverRecipients($packageData);
-
- // Now get an iterator
- $iteratorInstance = $discoveryInstance->getIterator();
-
- // Make sure the iterator instance is valid
- assert($iteratorInstance instanceof Iterator);
-
- // Rewind back to the beginning
- $iteratorInstance->rewind();
-
- // ... and begin iteration
- while ($iteratorInstance->valid()) {
- // Get current entry
- $currentRecipient = $iteratorInstance->current();
-
- // Debug message
- //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('NETWORK-PACKAGE: Setting recipient to ' . $currentRecipient . ',previous=' . $packageData[self::PACKAGE_DATA_RECIPIENT]);
-
- // Set the recipient
- $packageData[self::PACKAGE_DATA_RECIPIENT] = $currentRecipient;
-
- // Push the declared package to the next stack.
- $this->getStackInstance()->pushNamed(self::STACKER_NAME_DECLARED, $packageData);
-
- // Debug message
- //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('NETWORK-PACKAGE: Package declared for recipient ' . $currentRecipient);
-
- // Skip to next entry
- $iteratorInstance->next();
- } // END - while
-
- /*
- * The recipient list can be cleaned up here because the package which
- * shall be delivered has already been added for all entries from the
- * list.
- */
- $discoveryInstance->clearRecipients();
- }
-
- /**
- * Delivers raw package data. In short, this will discover the raw socket
- * resource through a discovery class (which will analyse the receipient of
- * the package), register the socket with the connection (handler/helper?)
- * instance and finally push the raw data on our outgoing queue.
- *
- * @param $packageData Raw package data in an array
- * @return void
- */
- private function deliverRawPackageData (array $packageData) {
- // Trace message
- //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('NETWORK-PACKAGE: packageData()=%d - CALLED!', count($packageData)));
-
- /*
- * This package may become big, depending on the shared object size or
- * delivered message size which shouldn't be so long (to save
- * bandwidth). Because of the nature of the used protocol (TCP) we need
- * to split it up into smaller pieces to fit it into a TCP frame.
- *
- * So first we need (again) a discovery class but now a protocol
- * discovery to choose the right socket resource. The discovery class
- * should take a look at the raw package data itself and then decide
- * which (configurable!) protocol should be used for that type of
- * package.
- */
- $discoveryInstance = SocketDiscoveryFactory::createSocketDiscoveryInstance();
-
- // Now discover the right socket instance from given package data
- $socketInstance = $discoveryInstance->discoverSocket($packageData, StorableSocket::CONNECTION_TYPE_OUTGOING);
-
- // Debug message
- //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('NETWORK-PACKAGE: Reached line ' . __LINE__ . ' after discoverSocket() has been called.');
-
- // Get the connection helper from registry
- $helperInstance = GenericRegistry::getRegistry()->getInstance('connection');
-
- // Debug message
- //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('NETWORK-PACKAGE: stateInstance=' . $helperInstance->getStateInstance());
-
- // And make sure it is valid
- assert($helperInstance instanceof ConnectionHelper);
-
- // Get connection info class
- $infoInstance = ConnectionInfoFactory::createConnectionInfoInstance($helperInstance->getProtocolName(), 'helper');
-
- // Will the info instance with connection helper data
- $infoInstance->fillWithConnectionHelperInformation($helperInstance);
-
- // Debug message
- //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('NETWORK-PACKAGE: Reached line ' . __LINE__ . ' before isSocketRegistered() has been called.');
-
- // Is it not there?
- if (($socketInstance->isValidSocket()) && (!$this->getRegistryInstance()->isSocketRegistered($infoInstance, $socketInstance))) {
- // Debug message
- //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('NETWORK-PACKAGE: Registering socket ' . $socketInstance . ' ...');
-
- // Then register it
- $this->getRegistryInstance()->registerSocketInstance($infoInstance, $socketInstance, $packageData);
- } elseif (!$helperInstance->getStateInstance()->isPeerStateConnected()) {
- // Is not connected, then we cannot send
- self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('NETWORK-PACKAGE: Unexpected peer state ' . $helperInstance->getStateInstance()->__toString() . ' detected.');
-
- // Shutdown the socket
- $socketInstance->shutdownSocket();
- }
-
- // Debug message
- //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('NETWORK-PACKAGE: Reached line ' . __LINE__ . ' after isSocketRegistered() has been called.');
-
- // Make sure the connection is up
- $helperInstance->getStateInstance()->validatePeerStateConnected();
-
- // Debug message
- //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('NETWORK-PACKAGE: Reached line ' . __LINE__ . ' after validatePeerStateConnected() has been called.');
-
- // Enqueue it again on the out-going queue, the connection is up and working at this point
- $this->getStackInstance()->pushNamed(self::STACKER_NAME_OUTGOING, $packageData);
-
- // Debug message
- //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('NETWORK-PACKAGE: Reached line ' . __LINE__ . ' after pushNamed() has been called.');
- }
-
- /**
- * Sends waiting packages
- *
- * @param $packageData Raw package data
- * @return void
- */
- private function sendOutgoingRawPackageData (array $packageData) {
- // Trace message
- //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('NETWORK-PACKAGE: packageData()=%d - CALLED!', count($packageData)));
-
- // Init sent bytes
- $sentBytes = 0;
-
- // Get the right connection instance
- $infoInstance = $this->getRegistryInstance()->getInfoInstanceFromPackageData($packageData);
-
- // Test helper instance
- assert($infoInstance instanceof ShareableInfo);
-
- // Get helper instance
- $helperInstance = $infoInstance->getHelperInstance();
-
- // Some sanity-checks on the object
- //* DEBUG-DIE: */ die(': p1=' . $infoInstance->getProtocolName() . ',p2=' . $helperInstance->getProtocolName() . ',infoInstance=' . print_r($infoInstance, TRUE));
- assert($helperInstance instanceof ConnectionHelper);
- assert($infoInstance->getProtocolName() == $helperInstance->getProtocolName());
-
- // Is this connection still alive?
- if ($helperInstance->isShuttedDown()) {
- // This connection is shutting down
- // @TODO We may want to do somthing more here?
- return;
- } // END - if
-
- // Sent out package data
- $helperInstance->sendRawPackageData($packageData);
-
- // Debug message
- //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('NETWORK-PACKAGE: EXIT!');
- }
-
- /**
- * Generates a secure hash for given raw package content and sender id
- *
- * @param $content Raw package data
- * @param $senderId Sender id to generate a hash for
- * @return $hash Hash as hex-encoded string
- */
- private function generatePackageHash ($content, $senderId) {
- // Debug message
- //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('NETWORK-PACKAGE: content()=' . strlen($content) . ',senderId=' . $senderId . ' - CALLED!');
-
- // Assert on variables
- assert(!empty($content));
- assert(!empty($senderId));
-
- // Is the feature enabled?
- if (!FrameworkFeature::isFeatureAvailable('hubcoin_reward')) {
- // Feature is not enabled
- //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('NETWORK-PACKAGE: Feature "hubcoin_reward" not available, not generating package hash. Returning NULL ...');
- return NULL;
- } // END - if
-
- // Fake array
- $data = array(
- self::PACKAGE_CONTENT_SENDER => $senderId,
- self::PACKAGE_CONTENT_MESSAGE => $content,
- self::PACKAGE_CONTENT_PRIVATE_KEY_HASH => $this->getPrivateKeyHash(),
- );
-
- // Hash content and sender id together, use scrypt
- //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('NETWORK-PACKAGE: senderId=' . $senderId . ',content()=' . strlen($content));
- $hash = FrameworkFeature::callFeature('hubcoin_reward', 'generateHash', array($senderId . ':' . $content . ':' . $this->determineSenderPrivateKeyHash($data)));
-
- // Debug message
- //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('NETWORK-PACKAGE: hash=' . $hash . ' - EXIT!');
-
- // Return it
- return $hash;
- }
-
- /**
- * Checks whether the hash 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 $isHashValid Whether the hash is valid
- * @todo Unfinished area, hashes are currently NOT fully supported
- */
- private function isPackageHashValid (array $decodedArray) {
- // Debug message
- //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('NETWORK-PACKAGE: decodedArray=' . print_r($decodedArray, TRUE) . ' - CALLED!');
-
- // Make sure the required array elements are there
- assert(isset($decodedArray[self::PACKAGE_CONTENT_SENDER]));
- assert(isset($decodedArray[self::PACKAGE_CONTENT_MESSAGE]));
- assert(isset($decodedArray[self::PACKAGE_CONTENT_HASH]));
- assert(isset($decodedArray[self::PACKAGE_CONTENT_PRIVATE_KEY_HASH]));
-
- // Is the feature enabled?
- if (!FrameworkFeature::isFeatureAvailable('hubcoin_reward')) {
- // Feature is not enabled, so hashes are always valid
- //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('NETWORK-PACKAGE: Feature "hubcoin_reward" not available, not checking hash. Returning TRUE ...');
- return TRUE;
- } // END - if
-
- // Check validity
- //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('NETWORK-PACKAGE: senderId=' . $decodedArray[self::PACKAGE_CONTENT_SENDER] . ',message()=' . strlen($decodedArray[self::PACKAGE_CONTENT_MESSAGE]) . ',hash=' . $decodedArray[self::PACKAGE_CONTENT_HASH]);
- //* DEBUG-DIE: */ die(__METHOD__ . ': decodedArray=' . print_r($decodedArray, TRUE));
- $isHashValid = FrameworkFeature::callFeature('hubcoin_reward', 'checkHash', array($decodedArray[self::PACKAGE_CONTENT_SENDER] . ':' . $decodedArray[self::PACKAGE_CONTENT_MESSAGE] . ':' . $this->determineSenderPrivateKeyHash($decodedArray), $decodedArray[self::PACKAGE_CONTENT_HASH]));
-
- // Return it
- //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('NETWORK-PACKAGE: isHashValid=' . intval($isHashValid) . ' - EXIT!');
- return $isHashValid;
- }
-
- /**
- * "Enqueues" raw content into this delivery class by reading the raw content
- * from given helper's template instance and pushing it on the 'undeclared'
- * stack.
- *
- * @param $helperInstance An instance of a HubHelper class
- * @return void
- */
- public function enqueueRawDataFromTemplate (HubHelper $helperInstance) {
- // Debug message
- //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('NETWORK-PACKAGE: CALLED!');
-
- // Get the raw content ...
- $content = $helperInstance->getTemplateInstance()->getRawTemplateData();
- //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('content(' . strlen($content) . ')=' . $content);
-
- // ... and compress it
- $compressed = $this->getCompressorInstance()->compressStream($content);
-
- // Add magic in front of it and hash behind it, including BASE64 encoding
- $packageContent = sprintf(self::PACKAGE_MASK,
- // 1.) Compressor's extension
- $this->getCompressorInstance()->getCompressorExtension(),
- // - separator
- self::PACKAGE_MASK_SEPARATOR,
- // 2.) Compressed raw package content, encoded with BASE64
- base64_encode($compressed),
- // - separator
- self::PACKAGE_MASK_SEPARATOR,
- // 3.) Tags
- implode(self::PACKAGE_TAGS_SEPARATOR, $helperInstance->getPackageTags()),
- // - separator
- self::PACKAGE_MASK_SEPARATOR,
- // 4.) Checksum
- $this->getHashFromContent($compressed)
- );
-
- // Debug message
- //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('NETWORK-PACKAGE: Enqueueing package for recipientType=' . $helperInstance->getRecipientType() . ' ...');
-
- // Make sure required data is there
- assert(!empty($content));
- assert($this->getSessionId() != '');
-
- // Now prepare the temporary array and push it on the 'undeclared' stack
- $this->getStackInstance()->pushNamed(self::STACKER_NAME_UNDECLARED, array(
- self::PACKAGE_DATA_SENDER_ADDRESS => $this->getSessionId(),
- self::PACKAGE_DATA_SENDER_PORT => '0',
- self::PACKAGE_DATA_RECIPIENT => $helperInstance->getRecipientType(),
- self::PACKAGE_DATA_CONTENT => $packageContent,
- self::PACKAGE_DATA_STATUS => self::PACKAGE_STATUS_NEW,
- self::PACKAGE_DATA_HASH => $this->generatePackageHash($content, $this->getSessionId()),
- self::PACKAGE_DATA_PRIVATE_KEY_HASH => $this->getPrivateKeyHash(),
- ));
-
- // Debug message
- //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('NETWORK-PACKAGE: EXIT!');
- }
-
- /**
- * Checks whether a package has been enqueued for delivery.
- *
- * @return $isEnqueued Whether a package is enqueued
- */
- public function isPackageEnqueued () {
- // Check whether the stacker is not empty
- $isEnqueued = (($this->getStackInstance()->isStackInitialized(self::STACKER_NAME_UNDECLARED)) && (!$this->getStackInstance()->isStackEmpty(self::STACKER_NAME_UNDECLARED)));
-
- // Trace message
- //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('NETWORK-PACKAGE: isEnqueued=%d - EXIT!', intval($isEnqueued)));
-
- // Return the result
- return $isEnqueued;
- }
-
- /**
- * Checks whether a package has been declared
- *
- * @return $isDeclared Whether a package is declared
- */
- public function isPackageDeclared () {
- // Check whether the stacker is not empty
- $isDeclared = (($this->getStackInstance()->isStackInitialized(self::STACKER_NAME_DECLARED)) && (!$this->getStackInstance()->isStackEmpty(self::STACKER_NAME_DECLARED)));
-
- // Trace message
- //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('NETWORK-PACKAGE: isDeclared=%d - EXIT!', intval($isDeclared)));
-
- // Return the result
- return $isDeclared;
- }
-
- /**
- * Checks whether a package should be sent out
- *
- * @return $isWaitingDelivery Whether a package is waiting for delivery
- */
- public function isPackageWaitingForDelivery () {
- // Check whether the stacker is not empty
- $isWaitingDelivery = (($this->getStackInstance()->isStackInitialized(self::STACKER_NAME_OUTGOING)) && (!$this->getStackInstance()->isStackEmpty(self::STACKER_NAME_OUTGOING)));
-
- // Trace message
- //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('NETWORK-PACKAGE: isWaitingDelivery=%d - EXIT!', intval($isWaitingDelivery)));
-
- // Return the result
- return $isWaitingDelivery;
- }
-
- /**
- * Checks whether encoded (raw) data is pending
- *
- * @return $isPending Whether encoded data is pending
- */
- public function isEncodedDataPending () {
- // Check whether the stacker is not empty
- $isPending = (($this->getStackInstance()->isStackInitialized(self::STACKER_NAME_OUTGOING_STREAM)) && (!$this->getStackInstance()->isStackEmpty(self::STACKER_NAME_OUTGOING_STREAM)));
-
- // Trace message
- //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('NETWORK-PACKAGE: isPending=%d - EXIT!', intval($isPending)));
-
- // Return the result
- return $isPending;
- }
-
- /**
- * Delivers an enqueued package to the stated destination. If a non-session
- * id is provided, recipient resolver is being asked (and instanced once).
- * This allows that a single package is being delivered to multiple targets
- * without enqueueing it for every target. If no target is provided or it
- * can't be determined a NoTargetException is being thrown.
- *
- * @return void
- * @throws NoTargetException If no target can't be determined
- */
- public function declareEnqueuedPackage () {
- // Debug message
- //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('NETWORK-PACKAGE: CALLED!');
-
- // Make sure this method isn't working if there is no package enqueued
- if (!$this->isPackageEnqueued()) {
- // This is not fatal but should be avoided
- self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('NETWORK-PACKAGE: No raw package data waiting declaration, but ' . __METHOD__ . ' has been called!');
- return;
- } // END - if
-
- /*
- * Now there are for sure packages to deliver, so start with the first
- * one.
- */
- $packageData = $this->getStackInstance()->popNamed(self::STACKER_NAME_UNDECLARED);
-
- // Declare the raw package data for delivery
- $this->declareRawPackageData($packageData);
-
- // Debug message
- //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('NETWORK-PACKAGE: EXIT!');
- }
-
- /**
- * Delivers the next declared package. Only one package per time will be sent
- * because this may take time and slows down the whole delivery
- * infrastructure.
- *
- * @return void
- */
- public function processDeclaredPackage () {
- // Debug message
- //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('NETWORK-PACKAGE: CALLED!');
-
- // Sanity check if we have packages declared
- if (!$this->isPackageDeclared()) {
- // This is not fatal but should be avoided
- self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('NETWORK-PACKAGE: No package has been declared, but ' . __METHOD__ . ' has been called!');
- return;
- } // END - if
-
- // Get the package
- $packageData = $this->getStackInstance()->getNamed(self::STACKER_NAME_DECLARED);
-
- // Assert on it
- assert(isset($packageData[self::PACKAGE_DATA_RECIPIENT]));
-
- // Try to deliver the package
- try {
- // And try to send it
- $this->deliverRawPackageData($packageData);
-
- // And remove it finally
- $this->getStackInstance()->popNamed(self::STACKER_NAME_DECLARED);
- } catch (UnexpectedStateException $e) {
- // The state is not excepected (shall be 'connected')
- self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('NETWORK-PACKAGE: Caught ' . $e->__toString() . ',message=' . $e->getMessage());
-
- // Mark the package with status failed
- $this->changePackageStatus($packageData, self::STACKER_NAME_DECLARED, self::PACKAGE_STATUS_FAILED);
- }
-
- // Debug message
- //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('NETWORK-PACKAGE: EXIT!');
- }
-
- /**
- * Sends waiting packages out for delivery
- *
- * @return void
- */
- public function sendWaitingPackage () {
- // Debug message
- //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('NETWORK-PACKAGE: CALLED!');
-
- // Sanity check if we have packages waiting for delivery
- if (!$this->isPackageWaitingForDelivery()) {
- // This is not fatal but should be avoided
- self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('NETWORK-PACKAGE: No package is waiting for delivery, but ' . __METHOD__ . ' was called.');
- return;
- } // END - if
-
- // Get the package
- $packageData = $this->getStackInstance()->getNamed(self::STACKER_NAME_OUTGOING);
-
- try {
- // Now try to send it
- $this->sendOutgoingRawPackageData($packageData);
-
- // And remove it finally
- $this->getStackInstance()->popNamed(self::STACKER_NAME_OUTGOING);
- } catch (InvalidSocketException $e) {
- // Output exception message
- self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('NETWORK-PACKAGE: Package was not delivered: ' . $e->getMessage());
-
- // Mark package as failed
- $this->changePackageStatus($packageData, self::STACKER_NAME_OUTGOING, self::PACKAGE_STATUS_FAILED);
- }
-
- // Debug message
- //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('NETWORK-PACKAGE: EXIT!');
- }
-
- /**
- * Sends out encoded data to a socket
- *
- * @return void
- */
- public function sendEncodedData () {
- // Debug message
- /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('NETWORK-PACKAGE: CALLED!');
-
- // Make sure there is pending encoded data
- assert($this->isEncodedDataPending());
-
- // Pop current data from stack
- $encodedDataArray = $this->getStackInstance()->popNamed(self::STACKER_NAME_OUTGOING_STREAM);
-
- // Init in this round sent bytes
- $sentBytes = 0;
-
- // Assert on socket instance
- assert(isset($encodedDataArray[self::RAW_INDEX_SOCKET_INSTANCE]));
- assert($encodedDataArray[self::RAW_INDEX_SOCKET_INSTANCE] instanceof StorableSocket);
- assert($encodedDataArray[self::RAW_INDEX_SOCKET_INSTANCE]->isValidSocket());
-
- // Get socket instance and remove it from array
- $socketInstance = $encodedDataArray[self::RAW_INDEX_SOCKET_INSTANCE];
- $encodedDataArray[self::RAW_INDEX_SOCKET_INSTANCE] = NULL;
-
- // Trace message
- /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('NETWORK-PACKAGE: Calling socketInstance->writeBufferToSocketByArray(%d,%d) ...', count($encodedDataArray), $sentBytes));
-
- // And deliver it
- if (!$socketInstance->writeBufferToSocketByArray($encodedDataArray, $sentBytes)) {
- // Something bad happened while writing to socket
- $socketInstance->handleSocketError(__METHOD__, __LINE__, array('0.0.0.0', '0'));
- } // END - if
-
- // Debug message
- /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('NETWORK-PACKAGE: sentBytes[%s]=%d', gettype($sentBytes), $sentBytes));
-
- // If there was an error, don't continue here
- if (($sentBytes === 0) && (strlen($encodedDataArray[self::RAW_INDEX_ENCODED_DATA]) > 0)) {
- // Nothing sent means all data has been sent
- /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('CONNECTION-HELPER: All sent! (LINE=' . __LINE__ . ')');
- return;
- } elseif (strlen($encodedDataArray[self::RAW_INDEX_ENCODED_DATA]) == 0) {
- // Abort here, all sent!
- /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('CONNECTION-HELPER: All sent! (LINE=' . __LINE__ . ')');
- return;
- }
-
- // Set it back
- $encodedDataArray[self::RAW_INDEX_SOCKET_INSTANCE] = $socketInstance;
-
- // Debug message
- /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('CONNECTION-HELPER: Pushing raw data back to stacker, as still some data is pending delivery.');
-
- // Push array back in stack
- $this->getStackInstance()->pushNamed(self::STACKER_NAME_OUTGOING_STREAM, $encodedDataArray);
-
- // Debug message
- /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('NETWORK-PACKAGE: EXIT!');
- }
-
- ///////////////////////////////////////////////////////////////////////////
- // Receiving packages / raw data
- ///////////////////////////////////////////////////////////////////////////
-
- /**
- * Checks whether decoded raw data is pending
- *
- * @return $isPending Whether decoded raw data is pending
- */
- private function isRawDataPending () {
- // Trace message
- //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('NETWORK-PACKAGE: CALLED!');
-
- // Just return whether the stack is not empty
- $isPending = (!$this->getStackInstance()->isStackEmpty(self::STACKER_NAME_DECODED_INCOMING));
-
- // Trace message
- //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('NETWORK-PACKAGE: isPending=%d - EXIT!', intval($isPending)));
-
- // Return the status
- return $isPending;
- }
-
- /**
- * Checks whether new raw package data has arrived at a socket
- *
- * @return $hasArrived Whether new raw package data has arrived for processing
- */
- public function isNewRawDataPending () {
- // Trace message
- //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('NETWORK-PACKAGE: Calling this->getListenerPoolInstance()->accept(%s) ... - CALLED!', $this->getVisitorInstance()));
-
- // Visit the pool. This monitors the pool for incoming raw data.
- $this->getListenerPoolInstance()->accept($this->getVisitorInstance());
-
- // Check for new data arrival
- $hasArrived = $this->isRawDataPending();
-
- // Trace message
- //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('NETWORK-PACKAGE: hasArrived=%d - EXIT!', intval($hasArrived)));
-
- // Return the status
- return $hasArrived;
- }
-
- /**
- * Handles the incoming decoded raw data. This method does not "convert" the
- * decoded data back into a package array, it just "handles" it and pushs it
- * on the next stack.
- *
- * @return void
- */
- public function handleIncomingDecodedData () {
- /*
- * This method should only be called if decoded raw data is pending,
- * so check it again.
- */
- if (!$this->isRawDataPending()) {
- // This is not fatal but should be avoided
- self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('NETWORK-PACKAGE: No raw (decoded?) data is pending, but ' . __METHOD__ . ' has been called!');
- return;
- } // END - if
-
- // Very noisy debug message:
- //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('NETWORK-PACKAGE: Stacker size is ' . $this->getStackInstance()->getStackCount(self::STACKER_NAME_DECODED_INCOMING) . ' entries.');
-
- // "Pop" the next entry (the same array again) from the stack
- $decodedData = $this->getStackInstance()->popNamed(self::STACKER_NAME_DECODED_INCOMING);
-
- // Make sure both array elements are there
- assert(
- (is_array($decodedData)) &&
- (isset($decodedData[HandleableRawData::PACKAGE_RAW_DATA])) &&
- (isset($decodedData[HandleableRawData::PACKAGE_ERROR_CODE]))
- );
-
- /*
- * Also make sure the error code is SOCKET_ERROR_UNHANDLED because we
- * only want to handle unhandled packages here.
- */
- //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('NETWORK-PACKAGE: errorCode=' . $decodedData[HandleableRawData::PACKAGE_ERROR_CODE] . '(' . StorableSocket::SOCKET_ERROR_UNHANDLED . ')');
- assert($decodedData[HandleableRawData::PACKAGE_ERROR_CODE] == StorableSocket::SOCKET_ERROR_UNHANDLED);
-
- // Remove the last chunk SEPARATOR (because there is no need for it)
- if (substr($decodedData[HandleableRawData::PACKAGE_RAW_DATA], -1, 1) == PackageFragmenter::CHUNK_SEPARATOR) {
- // It is there and should be removed
- $decodedData[HandleableRawData::PACKAGE_RAW_DATA] = substr($decodedData[HandleableRawData::PACKAGE_RAW_DATA], 0, -1);
- } // END - if
-
- // This package is "handled" and can be pushed on the next stack
- //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('NETWORK-PACKAGE: Pushing ' . strlen($decodedData[HandleableRawData::PACKAGE_RAW_DATA]) . ' bytes to stack ' . self::STACKER_NAME_DECODED_HANDLED . ' ...');
- $this->getStackInstance()->pushNamed(self::STACKER_NAME_DECODED_HANDLED, $decodedData);
- }
-
- /**
- * Adds raw decoded data from the given handler instance to this receiver
- *
- * @param $handlerInstance An instance of a Networkable class
- * @return void
- */
- public function addRawDataToIncomingStack (Networkable $handlerInstance) {
- /*
- * Get the decoded data from the handler, this is an array with
- * 'raw_data' and 'error_code' as elements.
- */
- $decodedData = $handlerInstance->getNextRawData();
-
- // Very noisy debug message:
- //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('NETWORK-PACKAGE: decodedData[' . gettype($decodedData) . ']=' . print_r($decodedData, TRUE));
-
- // And push it on our stack
- $this->getStackInstance()->pushNamed(self::STACKER_NAME_DECODED_INCOMING, $decodedData);
- }
-
- /**
- * Checks whether incoming decoded data is handled.
- *
- * @return $isHandled Whether incoming decoded data is handled
- */
- public function isIncomingRawDataHandled () {
- // Determine if the stack is not empty
- $isHandled = (!$this->getStackInstance()->isStackEmpty(self::STACKER_NAME_DECODED_HANDLED));
-
- // Return it
- return $isHandled;
- }
-
- /**
- * Checks whether the assembler has pending data left
- *
- * @return $isHandled Whether the assembler has pending data left
- */
- public function ifAssemblerHasPendingDataLeft () {
- // Determine if the stack is not empty
- $isHandled = (!$this->getAssemblerInstance()->isPendingDataEmpty());
-
- // Return it
- return $isHandled;
- }
-
- /**
- * Checks whether the assembler has multiple packages pending
- *
- * @return $isPending Whether the assembler has multiple packages pending
- */
- public function ifMultipleMessagesPending () {
- // Determine if the stack is not empty
- $isPending = ($this->getAssemblerInstance()->ifMultipleMessagesPending());
-
- // Return it
- return $isPending;
- }
-
- /**
- * Handles the attached assemler's pending data queue to be finally
- * assembled to the raw package data back.
- *
- * @return void
- */
- public function handleAssemblerPendingData () {
- // Debug message
- //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('NETWORK-PACKAGE: Calling this->getAssemblerInstance()->handlePendingData() ...');
-
- // Handle it
- $this->getAssemblerInstance()->handlePendingData();
- }
-
- /**
- * Handles multiple messages.
- *
- * @return void
- */
- public function handleMultipleMessages () {
- // Debug message
- //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('NETWORK-PACKAGE: Calling this->getAssemblerInstance()->handleMultipleMessages() ...');
-
- // Handle it
- $this->getAssemblerInstance()->handleMultipleMessages();
- }
-
- /**
- * Assembles incoming decoded data so it will become an abstract network
- * package again. The assembler does later do it's job by an other task,
- * not this one to keep best speed possible.
- *
- * @return void
- */
- public function assembleDecodedDataToPackage () {
- // Make sure the raw decoded package data is handled
- assert($this->isIncomingRawDataHandled());
-
- // Get current package content (an array with two elements; see handleIncomingDecodedData() for details)
- $packageContent = $this->getStackInstance()->getNamed(self::STACKER_NAME_DECODED_HANDLED);
-
- // Assert on some elements
- assert(
- (is_array($packageContent)) &&
- (isset($packageContent[HandleableRawData::PACKAGE_RAW_DATA])) &&
- (isset($packageContent[HandleableRawData::PACKAGE_ERROR_CODE]))
- );
-
- // Start assembling the raw package data array by chunking it
- $this->getAssemblerInstance()->chunkPackageContent($packageContent);
-
- // Remove the package from 'handled_decoded' stack ...
- $this->getStackInstance()->popNamed(self::STACKER_NAME_DECODED_HANDLED);
-
- // ... and push it on the 'chunked' stacker
- //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('NETWORK-PACKAGE: Pushing ' . strlen($packageContent[HandleableRawData::PACKAGE_RAW_DATA]) . ' bytes on stack ' . self::STACKER_NAME_DECODED_CHUNKED . ',packageContent=' . print_r($packageContent, TRUE));
- $this->getStackInstance()->pushNamed(self::STACKER_NAME_DECODED_CHUNKED, $packageContent);
- }
-
- /**
- * Accepts the visitor to process the visit "request"
- *
- * @param $visitorInstance An instance of a Visitor class
- * @return void
- */
- public function accept (Visitor $visitorInstance) {
- // Debug message
- //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('NETWORK-PACKAGE: ' . $visitorInstance->__toString() . ' has visited - CALLED!');
-
- // Visit the package
- $visitorInstance->visitNetworkPackage($this);
-
- // Then visit the assembler to handle multiple packages
- $this->getAssemblerInstance()->accept($visitorInstance);
-
- // Debug message
- //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('NETWORK-PACKAGE: ' . $visitorInstance->__toString() . ' has visited - EXIT!');
- }
-
- /**
- * Clears all stacks
- *
- * @return void
- */
- public function clearAllStacks () {
- // Call the init method to force re-initialization
- $this->initStacks(TRUE);
-
- // Debug message
- //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('NETWORK-PACKAGE: All stacker have been re-initialized.');
- }
-
- /**
- * Removes the first failed outoging package from the stack to continue
- * with next one (it will never work until the issue is fixed by you).
- *
- * @return void
- * @throws UnexpectedPackageStatusException If the package status is not 'failed'
- * @todo This may be enchanced for outgoing packages?
- */
- public function removeFirstFailedPackage () {
- // Get the package again
- $packageData = $this->getStackInstance()->getNamed(self::STACKER_NAME_DECLARED);
-
- // Is the package status 'failed'?
- if ($packageData[self::PACKAGE_DATA_STATUS] != self::PACKAGE_STATUS_FAILED) {
- // Not failed!
- throw new UnexpectedPackageStatusException(array($this, $packageData, self::PACKAGE_STATUS_FAILED), self::EXCEPTION_UNEXPECTED_PACKAGE_STATUS);
- } // END - if
-
- // Remove this entry
- $this->getStackInstance()->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);
-
- // Debug message
- //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('NETWORK-PACKAGE: decodedArray=' . print_r($decodedArray, TRUE));
-
- // Assert on count (should be always 3)
- assert(count($decodedArray) == self::DECODED_DATA_ARRAY_SIZE);
-
- /*
- * Create 'decodedData' array with all assoziative array elements.
- */
- $decodedData = array(
- self::PACKAGE_DATA_SENDER_ADDRESS => $decodedArray[self::INDEX_PACKAGE_SENDER_ADDRESS],
- self::PACKAGE_DATA_SENDER_PORT => $decodedArray[self::INDEX_PACKAGE_SENDER_PORT],
- 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_HASH => $decodedArray[self::INDEX_PACKAGE_HASH],
- self::PACKAGE_DATA_PRIVATE_KEY_HASH => $decodedArray[self::INDEX_PACKAGE_PRIVATE_KEY_HASH]
- );
-
- // 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 handleRawData (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. This is much
- * better to remember than plain numbers, isn't it?
- */
- $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 but still compressed
- 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],
- // Sender's id
- self::PACKAGE_CONTENT_SENDER => $decodedData[self::PACKAGE_DATA_SENDER_ADDRESS],
- // Hash from decoded raw data
- self::PACKAGE_CONTENT_HASH => $decodedData[self::PACKAGE_DATA_HASH],
- // Hash of private key
- self::PACKAGE_CONTENT_PRIVATE_KEY_HASH => $decodedData[self::PACKAGE_DATA_PRIVATE_KEY_HASH]
- );
-
- // 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), self::EXCEPTION_INVALID_DATA_CHECKSUM);
- } // END - if
-
- /*
- * The checksum is the same, then it can be decompressed safely. The
- * original message is at this point fully decoded.
- */
- $decodedContent[self::PACKAGE_CONTENT_MESSAGE] = $this->getCompressorInstance()->decompressStream($decodedContent[self::PACKAGE_CONTENT_MESSAGE]);
-
- // And push it on the next stack
- $this->getStackInstance()->pushNamed(self::STACKER_NAME_NEW_MESSAGE, $decodedContent);
- }
-
- /**
- * Checks whether a new message has arrived
- *
- * @return $hasArrived Whether a new message has arrived for processing
- */
- public function isNewMessageArrived () {
- // Determine if the stack is not empty
- $hasArrived = (!$this->getStackInstance()->isStackEmpty(self::STACKER_NAME_NEW_MESSAGE));
-
- // Return it
- return $hasArrived;
- }
-
- /**
- * Handles newly arrived messages
- *
- * @return void
- * @todo Implement verification of all sent tags here?
- */
- public function handleNewlyArrivedMessage () {
- // Make sure there is at least one message
- assert($this->isNewMessageArrived());
-
- // Get it from the stacker, it is the full array with the decoded message
- $decodedContent = $this->getStackInstance()->popNamed(self::STACKER_NAME_NEW_MESSAGE);
-
- // Generate the hash of comparing it
- if (!$this->isPackageHashValid($decodedContent)) {
- // Is not valid, so throw an exception here
- exit(__METHOD__ . ':INVALID HASH! UNDER CONSTRUCTION!' . chr(10));
- } // END - if
-
- // Now get a filter chain back from factory with given tags array
- $chainInstance = PackageFilterChainFactory::createChainByTagsArray($decodedContent[self::PACKAGE_CONTENT_TAGS]);
-
- /*
- * Process the message through all filters, note that all other
- * elements from $decodedContent are no longer needed.
- */
- $chainInstance->processMessage($decodedContent, $this);
-
- /*
- * Post-processing of message data (this won't remove the message from
- * the stack).
- */
- $chainInstance->postProcessMessage($this);
- }
-
- /**
- * Checks whether a processed message is pending for "interpretation"
- *
- * @return $isPending Whether a processed message is pending
- */
- public function isProcessedMessagePending () {
- // Check it
- $isPending = (!$this->getStackInstance()->isStackEmpty(self::STACKER_NAME_PROCESSED_MESSAGE));
-
- // Return it
- return $isPending;
- }
-
- /**
- * Handle processed messages by "interpreting" the 'message_type' element
- *
- * @return void
- */
- public function handleProcessedMessage () {
- // Get it from the stacker, it is the full array with the processed message
- $messageArray = $this->getStackInstance()->popNamed(self::STACKER_NAME_PROCESSED_MESSAGE);
-
- // Add type for later easier handling
- $messageArray[self::MESSAGE_ARRAY_DATA][self::MESSAGE_ARRAY_TYPE] = $messageArray[self::MESSAGE_ARRAY_TYPE];
-
- // Debug message
- //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('NETWORK-PACKAGE: messageArray=' . print_r($messageArray, TRUE));
-
- // Create a handler instance from given message type
- $handlerInstance = MessageTypeHandlerFactory::createMessageTypeHandlerInstance($messageArray[self::MESSAGE_ARRAY_TYPE]);
-
- // Handle message data
- $handlerInstance->handleMessageData($messageArray[self::MESSAGE_ARRAY_DATA], $this);
-
- // Post-handling of message data
- $handlerInstance->postHandleMessageData($messageArray, $this);
- }
-
- /**
- * Feeds the hash and sender (as recipient for the 'sender' reward) to the
- * miner's queue, unless the message is not a "reward claim" message as this
- * leads to an endless loop. You may wish to run the miner to get some
- * reward ("Hubcoins") for "mining" this hash.
- *
- * @param $messageData Array with message data
- * @return void
- * @todo ~10% done?
- */
- public function feedHashToMiner (array $messageData) {
- // Debug message
- //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('NETWORK-PACKAGE: messageData()=%d - CALLED!', count($messageData)));
-
- // Is the feature enabled?
- if (!FrameworkFeature::isFeatureAvailable('hubcoin_reward')) {
- /*
- * Feature is not enabled, don't feed the hash to the miner as it
- *may be invalid.
- */
- return;
- } // END - if
-
- // Make sure the required elements are there
- assert(isset($messageData[self::MESSAGE_ARRAY_SENDER]));
- assert(isset($messageData[self::MESSAGE_ARRAY_HASH]));
- assert(isset($messageData[self::MESSAGE_ARRAY_DATA][self::MESSAGE_ARRAY_DATA_NODE_ID]));
-
- // Copy node id
- $messageData[self::MESSAGE_ARRAY_DATA_NODE_ID] = $messageData[self::MESSAGE_ARRAY_DATA][self::MESSAGE_ARRAY_DATA_NODE_ID];
-
- // Let's get rid of some fields that is not needed by the miner:
- unset($messageData[self::MESSAGE_ARRAY_TYPE]);
- unset($messageData[self::MESSAGE_ARRAY_DATA]);
-
- // Debug message
- //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('NETWORK-PACKAGE: messageData=' . print_r($messageData, TRUE));
-
- // Resolve session id ('sender' is a session id) into node id
- $nodeId = HubTools::resolveNodeIdBySessionId($messageData[self::MESSAGE_ARRAY_SENDER]);
-
- // Is 'claim_reward' the message type?
- if (in_array(Tagable::TAG_CLAIM_MINING_REWARD, $messageData[self::MESSAGE_ARRAY_TAGS])) {
- /*
- * Then don't feed this message to the miner as this causes an
- * endless loop of mining.
- */
- return;
- } // END - if
-
- // Also remove tags as the miner don't need this.
- unset($messageData[self::MESSAGE_ARRAY_TAGS]);
-
- // Unfinished stuff:
- $this->partialStub(sprintf('[%s:%d]: @TODO nodeId=%s,messageData=%s', __METHOD__, __LINE__, $nodeId, print_r($messageData, TRUE)));
- }
-
-}
--- /dev/null
+Deny from all
--- /dev/null
+<?php
+// Own namespace
+namespace Org\Shipsimu\Hub\Network\Package;
+
+// Import application-specific stuff
+use Org\Shipsimu\Hub\Generic\BaseHubSystem;
+
+// Import framework stuff
+use Org\Mxchange\CoreFramework\Registry\Registerable;
+
+/**
+ * A DeliverablePackage class for raw package data
+ *
+ * @author Roland Haeder <webmaster@shipsimu.org>
+ * @version 0.0.0
+ * @copyright Copyright (c) 2007, 2008 Roland Haeder, 2009 - 2018 Hub Developer Team
+ * @license GNU GPL 3.0 or any newer version
+ * @link http://www.shipsimu.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 PackageData extends BaseHubSystem implements DeliverablePackage, Registerable {
+ /**
+ * Protected constructor
+ *
+ * @return void
+ */
+ protected function __construct () {
+ // Call parent constructor
+ parent::__construct(__CLASS__);
+ }
+
+ /**
+ * Creates an instance of this class
+ *
+ * @return $packageInstance An instance of a PackageData class
+ */
+ public final static function createPackageData () {
+ // Get new instance
+ $packageInstance = new PackageData();
+
+ // Return the prepared instance
+ return $packageInstance;
+ }
+
+}
// Import application-specific stuff
use Org\Shipsimu\Hub\Generic\BaseHubSystem;
+use Org\Shipsimu\Hub\Handler\Package\NetworkPackageHandler;
use Org\Shipsimu\Hub\Helper\Connection\ConnectionHelper;
-use Org\Shipsimu\Hub\Network\Package\NetworkPackage;
+use Org\Shipsimu\Hub\Network\Package\DeliverablePackage;
// Import framework stuff
use Org\Mxchange\CoreFramework\Assertion\AssertionException;
/**
* "Getter" for processedPackages array index
*
- * @param $packageData Raw package data array
+ * @param $packageInstance An instance of a DeliverablePackage class array
* @return $index Array index for processedPackages
*/
- private function getProcessedPackagesIndex (array $packageData) {
+ private function getProcessedPackagesIndex (DeliverablePackage $packageInstance) {
return (
- $packageData[NetworkPackage::PACKAGE_DATA_SENDER_ADDRESS] . NetworkPackage::PACKAGE_DATA_SEPARATOR .
- $packageData[NetworkPackage::PACKAGE_DATA_RECIPIENT] . NetworkPackage::PACKAGE_DATA_SEPARATOR .
- $packageData[NetworkPackage::PACKAGE_DATA_CONTENT] . NetworkPackage::PACKAGE_DATA_SEPARATOR
+ $packageInstance->getSenderAddress() . NetworkPackageHandler::PACKAGE_DATA_SEPARATOR .
+ $packageInstance->getRecipient() . NetworkPackageHandler::PACKAGE_DATA_SEPARATOR .
+ $packageInstance->getContent() . NetworkPackageHandler::PACKAGE_DATA_SEPARATOR
);
}
/**
* Checks whether the given package data is already processed by this fragmenter
*
- * @param $packageData Raw package data array
+ * @param $packageData An instance of a DeliverablePackage class array
* @return $isProcessed Whether the package has been fragmented
*/
- private function isPackageProcessed (array $packageData) {
+ private function isPackageProcessed (DeliverablePackage $packageInstance) {
// Get array index
$index = $this->getProcessedPackagesIndex($packageData);
/**
* Marks the given package data as processed by this fragmenter
*
- * @param $packageData Raw package data array
+ * @param $packageData An instance of a DeliverablePackage class array
* @return void
*/
- private function markPackageDataProcessed (array $packageData) {
+ private function markPackageDataProcessed (DeliverablePackage $packageInstance) {
// Remember it (until we may remove it)
$this->processedPackages[$this->getProcessedPackagesIndex($packageData)] = TRUE;
}
/**
* Getter for final hash from given package data
*
- * @param $packageData Raw package data array
+ * @param $packageData An instance of a DeliverablePackage class array
* @return $finalHash Final hash for package data
*/
- private function getFinalHashFromPackageData (array $packageData) {
+ private function getFinalHashFromPackageInstance (DeliverablePackage $packageInstance) {
// Make sure it is there
assert(isset($this->processedPackages[$this->getProcessedPackagesIndex($packageData)]));
);
// Make sure the chunk is not larger than a TCP package can hold
- //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('PACKAGE-FRAGMENTER: assert: ' . strlen($rawData) . '/' . NetworkPackage::TCP_PACKAGE_SIZE . ' ...');
- // @TODO This assert broke packages where the hash chunk was very large: assert(strlen($rawData) <= NetworkPackage::TCP_PACKAGE_SIZE);
+ //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('PACKAGE-FRAGMENTER: assert: ' . strlen($rawData) . '/' . NetworkPackageHandler::TCP_PACKAGE_SIZE . ' ...');
+ // @TODO This assert broke packages where the hash chunk was very large: assert(strlen($rawData) <= NetworkPackageHandler::TCP_PACKAGE_SIZE);
// Add it to the array
if ($prepend === TRUE) {
* to all chunks and prepends a chunk with all hashes only in it. It will
* return the final hash for faster processing of packages.
*
- * @param $packageData Raw package data array
+ * @param $packageData An instance of a DeliverablePackage class array
* @param $helperInstance An instance of a ConnectionHelper class
* @return $finalHash Final hash for faster processing
* @todo $helperInstance is unused
*/
- public function fragmentPackageArray (array $packageData, ConnectionHelper $helperInstance) {
+ public function fragmentPackageArray (DeliverablePackage $packageInstance, ConnectionHelper $helperInstance) {
// Is this package already fragmented?
if (!$this->isPackageProcessed($packageData)) {
// First we need to "implode" the array
- $rawData = implode(NetworkPackage::PACKAGE_DATA_SEPARATOR, $packageData);
+ $rawData = implode(NetworkPackageHandler::PACKAGE_DATA_SEPARATOR, $packageInstance->getAllAsArray());
// Generate the final hash from the raw data (not encoded!)
$finalHash = $this->generateHashFromRawData($rawData);
$this->markPackageDataProcessed($packageData);
} else {
// Get the final hash from the package data
- $finalHash = $this->getFinalHashFromPackageData($packageData);
+ $finalHash = $this->getFinalHashFromPackageInstance($packageData);
}
// Return final hash
* the key is the chunk hash and value the raw chunk data.
*
* @param $finalHash Final hash for faster lookup
- * @return $rawDataChunk Raw package data chunk
+ * @return $rawDataChunk An instance of a DeliverablePackage class chunk
* @throws AssertionException If $finalHash was not 'TRUE'
*/
public function getNextRawDataChunk ($finalHash) {
use Org\Shipsimu\Hub\Container\Socket\StorableSocket;
use Org\Shipsimu\Hub\Connection\InvalidConnectionTypeException;
use Org\Shipsimu\Hub\Factory\Handler\Protocol\ProtocolHandlerFactory;
+use Org\Shipsimu\Hub\Handler\Package\NetworkPackageHandler;
use Org\Shipsimu\Hub\Listener\Listenable;
use Org\Shipsimu\Hub\Locator\Node\LocateableNode;
-use Org\Shipsimu\Hub\Network\Package\NetworkPackage;
+use Org\Shipsimu\Hub\Network\Package\DeliverablePackage;
use Org\Shipsimu\Hub\Pool\BasePool;
use Org\Shipsimu\Hub\Pool\Poolable;
use Org\Shipsimu\Hub\Pool\Peer\PoolablePeer;
/**
* "Getter" for a valid socket resource from given packae data.
*
- * @param $packageData Raw package data
+ * @param $packageData An instance of a DeliverablePackage class
* @param $connectionType Type of connection, can be 'incoming', 'outgoing', 'server' or default
* @return $socketInstance An instance of a StorableSocket class
* @throws InvalidConnectionTypeException If the provided connection type is not valid
* @throws LogicException If an expected array element is missing
*/
- public function getSocketFromPackageData (array $packageData, $connectionType = NULL) {
+ public function getSocketFromPackageInstance (DeliverablePackage $packageInstance, $connectionType = NULL) {
// Trace message
//* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('DEFAULT-PEER-POOL:packageData()=%d,connectionType[%s]=%s - CALLED!', count($packageData), gettype($connectionType), $connectionType));
$socketInstance = NULL;
// Resolve recipient (UNL) into a handler instance
- $handlerInstance = ProtocolHandlerFactory::createProtocolHandlerFromPackageData($packageData);
+ $handlerInstance = ProtocolHandlerFactory::createProtocolHandlerFromPackageInstance($packageData);
// Get UNL data
$unlInstance = $handlerInstance->getUniversalNodeLocatorInstance();
// Try to get the "peer"'s name
if (!$socketArray[Poolable::SOCKET_ARRAY_INSTANCE]->getSocketPeerName($peerAddress, $peerPort)) {
// Handle the socket error with given package data
- $socketArray[Poolable::SOCKET_ARRAY_INSTANCE]->handleSocketError(__METHOD__, __LINE__, explode(':', $packageData[NetworkPackage::PACKAGE_DATA_RECIPIENT]));
+ $socketArray[Poolable::SOCKET_ARRAY_INSTANCE]->handleSocketError(__METHOD__, __LINE__, explode(':', $packageInstance->getRecipient()));
} // END - if
// Debug message
// Import application-specific stuff
use Org\Shipsimu\Hub\Database\Frontend\Node\Dht\NodeDistributedHashTableDatabaseWrapper;
-use Org\Shipsimu\Hub\Network\Package\NetworkPackage;
+use Org\Shipsimu\Hub\Handler\Package\NetworkPackageHandler;
+use Org\Shipsimu\Hub\Network\Package\DeliverablePackage;
use Org\Shipsimu\Hub\Network\Recipient\BaseRecipient;
use Org\Shipsimu\Hub\Network\Recipient\Recipient;
*
* @param $recipient Recipient to resolve (e.g. could be a virtual recipient or direct session id)
* @param $listInstance An instance of a Listable class
- * @param $packageData Valid package data array
+ * @param $packageData An instance of a DeliverablePackage class
* @return void
* @throws FrameworkException Could throw different exceptions depending on implementation
*/
- public function resolveRecipient ($recipient, Listable $listInstance, array $packageData) {
+ public function resolveRecipient ($recipient, Listable $listInstance, DeliverablePackage $packageInstance) {
// Debug message
/* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('DHT-RECIPIENT: recipient=' . $recipient . ' - CALLED!');
// Make sure the recipient is valid
- assert($recipient == NetworkPackage::NETWORK_TARGET_DHT);
+ assert($recipient == NetworkPackageHandler::NETWORK_TARGET_DHT);
// Get recipient discovery instance
$discoverInstance = ObjectFactory::createObjectByConfiguredName('dht_recipient_discovery_class');
namespace Org\Shipsimu\Hub\Network\Recipient\Direct;
// Import application-specific sutff
-use Org\Shipsimu\Hub\Network\Package\NetworkPackage;
+use Org\Shipsimu\Hub\Handler\Package\NetworkPackageHandler;
+use Org\Shipsimu\Hub\Network\Package\DeliverablePackage;
use Org\Shipsimu\Hub\Network\Recipient\BaseRecipient;
use Org\Shipsimu\Hub\Network\Recipient\Recipient;
use Org\Shipsimu\Hub\Tools\HubTools;
*
* @param $recipient Recipient to resolve (e.g. could be a virtual recipient or direct session id)
* @param $listInstance An instance of a Listable class
- * @param $packageData Valid package data array
+ * @param $packageData An instance of a DeliverablePackage class
* @return $resolved Resolved recipient or VOID if only the set list has been filled
* @throws FrameworkException Could throw different exceptions depending on implementation
*/
- public function resolveRecipient ($recipient, Listable $listInstance, array $packageData) {
+ public function resolveRecipient ($recipient, Listable $listInstance, DeliverablePackage $packageInstance) {
// Debug message
/* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('DIRECT-RECIPIENT: recipient=' . $recipient);
// "Explode" all recipients
- $recipients = explode(NetworkPackage::PACKAGE_RECIPIENT_SEPARATOR, $recipient);
+ $recipients = explode(NetworkPackageHandler::PACKAGE_RECIPIENT_SEPARATOR, $recipient);
// Is maximum reached?
assert(count($recipients) <= $this->getConfigInstance()->getConfigEntry('package_recipient_max_count'));
namespace Org\Shipsimu\Hub\Network\Recipient\Loopback;
// Import application-specific sutff
-use Org\Shipsimu\Hub\Network\Package\NetworkPackage;
+use Org\Shipsimu\Hub\Handler\Package\NetworkPackageHandler;
+use Org\Shipsimu\Hub\Network\Package\DeliverablePackage;
use Org\Shipsimu\Hub\Network\Recipient\BaseRecipient;
use Org\Shipsimu\Hub\Network\Recipient\Recipient;
use Org\Shipsimu\Hub\Tools\HubTools;
*
* @param $recipient Recipient to resolve (e.g. could be a virtual recipient or direct session id)
* @param $listInstance An instance of a Listable class
- * @param $packageData Valid package data array
+ * @param $packageData An instance of a DeliverablePackage class
* @return $resolved Resolved recipient or VOID if only the set list has been filled
* @throws FrameworkException Could throw different exceptions depending on implementation
*/
- public function resolveRecipient ($recipient, Listable $listInstance, array $packageData) {
+ public function resolveRecipient ($recipient, Listable $listInstance, DeliverablePackage $packageInstance) {
// Make sure the recipient is valid
/* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('SELF-RECIPIENT: recipient=' . $recipient);
// @TODO Add more checks on data
- assert($recipient == NetworkPackage::NETWORK_TARGET_SELF);
+ assert($recipient == NetworkPackageHandler::NETWORK_TARGET_SELF);
// Determine IP or 'external_address' if set
$unl = HubTools::determineOwnExternalAddress();
// Import application-specific stuff
use Org\Shipsimu\Hub\Generic\BaseHubSystem;
-use Org\Shipsimu\Hub\Network\Package\NetworkPackage;
+use Org\Shipsimu\Hub\Handler\Package\NetworkPackageHandler;
+use Org\Shipsimu\Hub\Network\Package\DeliverablePackage;
use Org\Shipsimu\Hub\Network\Recipient\BaseRecipient;
use Org\Shipsimu\Hub\Network\Recipient\Recipient;
*
* @param $recipient Recipient to resolve (e.g. could be a virtual recipient or direct session id)
* @param $listInstance An instance of a Listable class
- * @param $packageData Valid package data array
+ * @param $packageData An instance of a DeliverablePackage class
* @return $resolved Resolved recipient or VOID if only the set list has been filled
* @throws FrameworkException Could throw different exceptions depending on implementation
*/
- public function resolveRecipient ($recipient, Listable $listInstance, array $packageData) {
+ public function resolveRecipient ($recipient, Listable $listInstance, DeliverablePackage $packageInstance) {
// Make sure the recipient is valid
/* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('UPPER-RECIPIENT: recipient=' . $recipient);
- assert($recipient == NetworkPackage::NETWORK_TARGET_UPPER);
+ assert($recipient == NetworkPackageHandler::NETWORK_TARGET_UPPER);
// Get all bootstrap nodes
foreach (explode(BaseHubSystem::BOOTSTRAP_NODES_SEPARATOR, $this->getConfigInstance()->getConfigEntry('hub_bootstrap_nodes')) as $unlData) {
// Import application-specific stuff
use Org\Shipsimu\Hub\Container\Socket\StorableSocket;
use Org\Shipsimu\Hub\Factory\Information\Connection\ConnectionInfoFactory;
+use Org\Shipsimu\Hub\Handler\Package\NetworkPackageHandler;
use Org\Shipsimu\Hub\Helper\Connection\ConnectionHelper;
use Org\Shipsimu\Hub\Information\ShareableInfo;
use Org\Shipsimu\Hub\Listener\BaseListener;
use Org\Shipsimu\Hub\Listener\Listenable;
-use Org\Shipsimu\Hub\Network\Package\NetworkPackage;
+use Org\Shipsimu\Hub\Network\Package\DeliverablePackage;
use Org\Shipsimu\Hub\Registry\Socket\RegisterableSocket;
// Import framework stuff
*
* @param $infoInstance An instance of a ShareableInfo class
* @param $socketInstance An instance of a StorableSocket class
- * @param $packageData Optional raw package data
* @throws SocketAlreadyRegisteredException If the given socket is already registered
* @return void
*/
- public function registerSocketInstance (ShareableInfo $infoInstance, StorableSocket $socketInstance, array $packageData = array()) {
+ public function registerSocketInstance (ShareableInfo $infoInstance, StorableSocket $socketInstance) {
// Debug message
//* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('SOCKET-REGISTRY: protocolName=' . $infoInstance->getProtocolName() . ',socketResource[' . gettype($socketInstance->getSocketResource()) . ']=' . $socketInstance->getSocketResource() . ' - CALLED!');
/**
* "Getter" for info instance from given package data
*
- * @param $packageData Raw package data
+ * @param $packageInstance An instance of a DeliverablePackage class
* @return $infoInstance An instance of a ShareableInfo class
*/
- public function getInfoInstanceFromPackageData (array $packageData) {
+ public function getInfoInstanceFromPackageInstance (DeliverablePackage $packageInstance) {
// Init info instance
$infoInstance = NULL;
//* DEBUG-DIE: */ die(__METHOD__ . ':packageData=' . print_r($packageData, TRUE));
//* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('SOCKET-REGISTRY: key=' . $key . ',subKey=' . $subKey . ',socketInstance=' . $socketInstance->__toString());
// Is this a StorableSocket instance and is the address the same?
- if (($socketInstance instanceof StorableSocket) && ($socketInstance->ifAddressMatches($packageData[NetworkPackage::PACKAGE_DATA_RECIPIENT]))) {
+ if (($socketInstance instanceof StorableSocket) && ($socketInstance->ifAddressMatches($packageInstance->getRecipient()))) {
// Debug die
//* DEBUG-DIE: */ die(__METHOD__ . ': socketInstance=' . print_r($socketInstance, TRUE));
*/
public function isIncomingSocketRegistered () {
// Trace message
- //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('SOCKET-REGISTRY: CALLED!');
+ /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('SOCKET-REGISTRY: CALLED!');
// Default is not found
$isRegistered = FALSE;
// Trace message
- //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('SOCKET-REGISTRY: isRegistered=%d - EXIT!', intval($isRegistered)));
+ /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('SOCKET-REGISTRY: isRegistered=%d - EXIT!', intval($isRegistered)));
// Return status
return $isRegistered;
use Org\Shipsimu\Hub\Container\Socket\StorableSocket;
use Org\Shipsimu\Hub\Factory\State\Peer\PeerStateFactory;
use Org\Shipsimu\Hub\Helper\Connection\ConnectionHelper;
+use Org\Shipsimu\Hub\Network\Package\DeliverablePackage;
use Org\Shipsimu\Hub\Resolver\State\BaseStateResolver;
use Org\Shipsimu\Hub\Resolver\State\StateResolver;
* Returns an state instance for a given raw package data and socket resource
*
* @param $helperInstance An instance of a ConnectionHelper class
- * @param $packageData Raw package data
+ * @param $packageData An instance of a DeliverablePackage class
* @param $socketInstance An instance of a StorableSocket class
* @return $stateInstance An instance of the resolved state
* @throws InvalidSocketException If socketResource, even from getSocketResource() is no valid resource
* @todo ~30% done
*/
- public static function resolveStateByPackage (ConnectionHelper $helperInstance, array $packageData, StorableSocket $socketInstance) {
+ public static function resolveStateByPackage (ConnectionHelper $helperInstance, DeliverablePackage $packageInstance, StorableSocket $socketInstance) {
// Get temporary resolver instance
$resolverInstance = self::createPeerStateResolver();
// Import application-specific stuff
use Org\Shipsimu\Hub\Factory\Handler\Protocol\ProtocolHandlerFactory;
use Org\Shipsimu\Hub\Factory\Registry\Object\ObjectTypeRegistryFactory;
+use Org\Shipsimu\Hub\Handler\Package\NetworkPackageHandler;
use Org\Shipsimu\Hub\Listener\Listenable;
-use Org\Shipsimu\Hub\Network\Package\NetworkPackage;
+use Org\Shipsimu\Hub\Network\Package\DeliverablePackage;
use Org\Shipsimu\Hub\Tag\BaseTag;
use Org\Shipsimu\Hub\Tag\Tagable;
use Org\Shipsimu\Hub\Template\Engine\Xml\ObjectRegistry\XmlObjectRegistryTemplateEngine;
/**
* Extracts the tags from given package data
*
- * @param $packageData Raw package data
+ * @param $packageData An instance of a DeliverablePackage class
* @return void
*/
- private function extractTagsFromPackageData (array $packageData) {
+ private function extractTagsFromPackageInstance (DeliverablePackage $packageInstance) {
// Debug message
//* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('TAGS: packageData=' . print_r($packageData, TRUE));
* We take a look at the tags (in most cases only one is needed) so
* first we need the content data splitted up into all it's parts.
*/
- $contentData = explode(NetworkPackage::PACKAGE_MASK_SEPARATOR, $packageData[NetworkPackage::PACKAGE_DATA_CONTENT]);
+ $contentData = explode(NetworkPackageHandler::PACKAGE_MASK_SEPARATOR, $packageInstance->getContent());
// Get the tags and store them locally
- $this->setTags(explode(NetworkPackage::PACKAGE_TAGS_SEPARATOR, $contentData[NetworkPackage::INDEX_TAGS]));
+ $this->setTags(explode(NetworkPackageHandler::PACKAGE_TAGS_SEPARATOR, $contentData[NetworkPackageHandler::INDEX_TAGS]));
}
/**
* shared over the whole hub-network. So if the "tag" (let's better say
* object type) isn't found in that XML the package won't be distributed.
*
- * @param $packageData Raw package data
+ * @param $packageData An instance of a DeliverablePackage class
* @return void
* @throws InvalidTagException If a provided tag from the package data is invalid
*/
- private function verifyAllTags (array $packageData) {
+ private function verifyAllTags (DeliverablePackage $packageInstance) {
// Get the registry
$objectRegistryInstance = ObjectTypeRegistryFactory::createObjectTypeRegistryInstance();
} // END - if
// Now save the last discovered protocol/recipient type
- $this->lastProtocol = ProtocolHandlerFactory::createProtocolHandlerFromPackageData($packageData);
+ $this->lastProtocol = ProtocolHandlerFactory::createProtocolHandlerFromPackageInstance($packageData);
$this->lastRecipientType = $entry[XmlObjectRegistryTemplateEngine::OBJECT_TYPE_DATA_RECIPIENT_TYPE];
} // END - foreach
}
/**
* Chooses the right protocol from given package data
*
- * @param $packageData Raw package data
+ * @param $packageData An instance of a DeliverablePackage class
* @return $lastProtocol An instance of the last used HandleableProtocol class
*/
- public function chooseProtocolFromPackageData (array $packageData) {
+ public function chooseProtocolFromPackageInstance (DeliverablePackage $packageInstance) {
// Extract the tags
- $this->extractTagsFromPackageData($packageData);
+ $this->extractTagsFromPackageInstance($packageData);
// Now we need to verify every single tag
$this->verifyAllTags($packageData);
/**
* Checks whether the given package data is accepted by the listener
*
- * @param $packageData Raw package data
+ * @param $packageData An instance of a DeliverablePackage class
* @param $listenerInstance A Listenable instance
* @return $accepts Whether it is accepted
*/
- public function ifPackageDataIsAcceptedByListener (array $packageData, Listenable $listenerInstance) {
+ public function ifPackageDataIsAcceptedByListener (DeliverablePackage $packageInstance, Listenable $listenerInstance) {
// Extract the tags
- $this->extractTagsFromPackageData($packageData);
+ $this->extractTagsFromPackageInstance($packageData);
// Now every single tag needs to be validated
$this->verifyAllTags($packageData);
//* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('NETWORK-PACKAGE-READER-TASK: CALLED!');
// Get package instance
- $packageInstance = NetworkPackageFactory::createNetworkPackageInstance();
+ $packageInstance = NetworkPackageHandlerFactory::createNetworkPackageHandlerInstance();
// Debug message
//* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('NETWORK-PACKAGE-READER-TASK: packageInstance=%s', $packageInstance->__toString()));
//* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('NETWORK-PACKAGE-WRITER-TASK: CALLED!');
// "Cache" package instance
- $packageInstance = NetworkPackageFactory::createNetworkPackageInstance();
+ $packageInstance = NetworkPackageHandlerFactory::createNetworkPackageHandlerInstance();
// Do we have something to deliver?
if ($packageInstance->isEncodedDataPending()) {
// Do we have reached the retry count?
if (ConnectionStatisticsHelper::isConnectRetryExhausted($helperInstance)) {
// Also visit the network package to clear any out-going packages
- NetworkPackageFactory::createNetworkPackageInstance()->accept($this);
+ NetworkPackageHandlerFactory::createNetworkPackageHandlerInstance()->accept($this);
- // Shutdown the connection helper (look in visitNetworkPackage() for details)
+ // Shutdown the connection helper (look in visitNetworkPackageHandler() for details)
$helperInstance->doShutdown();
} else {
// We can still move on and retry the connection attempt
* @param $packageInstance An instance of a Deliverable class
* @return void
*/
- public function visitNetworkPackage (Deliverable $packageInstance) {
+ public function visitNetworkPackageHandler (Deliverable $packageInstance) {
// Just call it back
$packageInstance->removeFirstFailedPackage();
}
// Do we have reached the retry count?
if (ConnectionStatisticsHelper::isConnectRetryExhausted($helperInstance)) {
// Also visit the network package to clear any out-going packages
- NetworkPackageFactory::createNetworkPackageInstance()->accept($this);
+ NetworkPackageHandlerFactory::createNetworkPackageHandlerInstance()->accept($this);
// Shutdown the connection
$helperInstance->doShutdown();
* @param $packageInstance An instance of a Deliverable class
* @return void
*/
- public function visitNetworkPackage (Deliverable $packageInstance) {
+ public function visitNetworkPackageHandler (Deliverable $packageInstance) {
// Just call it back
$packageInstance->clearAllStacks();
}
$cfg->setConfigEntry('node_ping_iterator_class', 'Org\Shipsimu\Hub\Iterator\Node\Ping\NodePingIterator');
// CFG: WEB-TEMPLATE-CLASS @OVERRIDE
-$cfg->setConfigEntry('web_template_class', 'ConsoleTemplateEngine');
+$cfg->setConfigEntry('web_template_class', 'Org\Mxchange\CoreFramework\Template\Engine\ConsoleTemplateEngine');
-// CFG: NETWORK-PACKAGE-CLASS
-$cfg->setConfigEntry('network_package_class', 'Org\Shipsimu\Hub\Network\Package\NetworkPackage');
+// CFG: PACKAGE-DATA-CLASS
+$cfg->setConfigEntry('package_data_class', 'Org\Shipsimu\Hub\Network\Package\PackageData');
+
+// CFG: NETWORK-PACKAGE-HANDLER-CLASS
+$cfg->setConfigEntry('network_package_handler_class', 'Org\Shipsimu\Hub\Handler\Package\NetworkPackageHandler');
// CFG: PACKAGE-COMPRESSOR-CLASS
$cfg->setConfigEntry('deco_package_compressor_class', 'Org\Shipsimu\Hub\Network\Compressor\Package\NetworkPackageCompressorDecorator');
namespace Org\Shipsimu\Hub\RawData;
// Import application-specific stuff
-use Org\Shipsimu\Hub\Network\Package\NetworkPackage;
+use Org\Shipsimu\Hub\Handler\Package\NetworkPackageHandler;
// Import framework stuff
use Org\Mxchange\CoreFramework\Generic\FrameworkException;
$message = sprintf('[%s:%d] The checksum %s doesnt match the checksum of the content: %s',
$messageArray[0]->__toString(),
$this->getLine(),
- $messageArray[0]->getHashFromContentSessionId($messageArray[1], $messageArray[2][NetworkPackage::PACKAGE_DATA_SENDER_ADDRESS]),
- $messageArray[1][NetworkPackage::PACKAGE_CONTENT_CHECKSUM]
+ $messageArray[0]->getHashFromContentSessionId($messageArray[1], $messageArray[2]->getSenderAddress()),
+ $messageArray[1][NetworkPackageHandler::PACKAGE_CONTENT_CHECKSUM]
);
// Call parent exception constructor
// Own namespace
namespace Org\Shipsimu\Hub\Status\Package;
-// Import application-specific stuff
-use Org\Shipsimu\Hub\Network\Package\NetworkPackage;
-
// Import framework stuff
use Org\Mxchange\CoreFramework\Generic\FrameworkException;
$message = sprintf('[%s:%d] Unexpected package status %s!=%s detected, recipient=%s, sender=%s:%d, hash=%s.',
$messageArray[0]->__toString(),
$this->getLine(),
- $messageArray[1][NetworkPackage::PACKAGE_DATA_STATUS],
+ $messageArray[1]->getPackageStatus(),
$messageArray[2],
- $messageArray[1][NetworkPackage::PACKAGE_DATA_RECIPIENT],
- $messageArray[1][NetworkPackage::PACKAGE_DATA_SENDER_ADDRESS],
- $messageArray[1][NetworkPackage::PACKAGE_DATA_SENDER_PORT],
- $messageArray[1][NetworkPackage::PACKAGE_DATA_HASH]
+ $messageArray[1]->getRecipient(),
+ $messageArray[1]->getSenderAddress(),
+ $messageArray[1]->getSenderPort(),
+ $messageArray[1]->getHash()
);
// Call parent exception constructor
namespace Org\Shipsimu\Hub\Peer;
// Import application-specific stuff
-use Org\Shipsimu\Hub\Network\Package\NetworkPackage;
+use Org\Shipsimu\Hub\Handler\Package\NetworkPackageHandler;
// Import framework stuff
use Org\Mxchange\CoreFramework\Generic\FrameworkException;
*/
public function __construct (array $messageArray, $code) {
// Construct the message
- $message = sprintf('[%s:%d] Sender %s is already registered.',
+ $message = sprintf('[%s:%d] Sender "%s" is already registered.',
$messageArray[0]->__toString(),
$this->getLine(),
- $messageArray[1][NetworkPackage::PACKAGE_DATA_SENDER_ADDRESS]
+ $messageArray[1]->getSenderAddress()
);
// Call parent exception constructor
namespace Org\Shipsimu\Hub\Unl;
// Import application-specific stuff
-use Org\Shipsimu\Hub\Network\Package\NetworkPackage;
+use Org\Shipsimu\Hub\Handler\Package\NetworkPackageHandler;
// Import framework stuff
use Org\Mxchange\CoreFramework\Generic\FrameworkException;
$messageArray[0]->__toString(),
$this->getLine(),
$messageArray[1]->__toString(),
- $messageArray[2][NetworkPackage::PACKAGE_DATA_RECIPIENT]
+ $messageArray[2]->getRecipient()
);
// Call parent exception constructor
const SOCKET_CONNECTED = 'connected'; // Nothing errorous happens, socket is connected
// Socket data array indexes
- const SOCKET_ARRAY_INDEX_FILE = 'socket_file';
+ // @deprecated Use a class instead of asociative array
const SOCKET_ARRAY_INDEX_ADDRESS = 'socket_address';
const SOCKET_ARRAY_INDEX_PORT = 'socket_port';
const SOCKET_ARRAY_INDEX_TYPE = 'socket_type';
// Own namespace
namespace Org\Shipsimu\Hub\Database\Frontend\Node\Dht;
+// Import application-specific stuff
+use Org\Shipsimu\Hub\Network\Package\DeliverablePackage;
+
// Import framework stuff
use Org\Mxchange\CoreFramework\Criteria\Local\LocalSearchCriteria;
use Org\Mxchange\CoreFramework\Database\Frontend\DatabaseWrapper;
/**
* Find recipients for given package data and returns it as a result instance
*
- * @param $packageData An array of valid package data
+ * @param $packageInstance An instance of a DeliverablePackage class
* @return $recipients An indexed array with DHT recipients
*/
- function getResultFromExcludedSender (array $packageData);
+ function getResultFromExcludedSender (DeliverablePackage $packageInstance);
/**
* Find recopients by given key/value pair. First look for the key and if it
// Import application-specific stuff
use Org\Shipsimu\Hub\Discovery\Recipient\DiscoverableRecipient;
+use Org\Shipsimu\Hub\Network\Package\DeliverablePackage;
/**
* An interface for DHT recipient discovery
/**
* Resolves one or more recipients for a DHT transfer by given package data.
*
- * @param $packageData Valid package data array
+ * @param $packageInstance An instance of a DeliverablePackage class
* @return $recipients An indexed array with DHT recipients
*/
- function resolveRecipientsByPackageData (array $packageData);
+ function resolveRecipientsByPackageData (DeliverablePackage $packageInstance);
}
// Import application-specific stuff
use Org\Shipsimu\Hub\Discovery\Recipient\DiscoverableRecipient;
+use Org\Shipsimu\Hub\Network\Package\DeliverablePackage;
/**
* An interface for node recipient discovery
/**
* Tries to discover all recipients for given package data
*
- * @param $packageData Raw package data array
+ * @param $packageInstance An instance of a DeliverablePackage class array
* @return void
*/
- function discoverRecipients (array $packageData);
+ function discoverRecipients (DeliverablePackage $packageInstance);
/**
* Tries to discover all recipients by given decoded package data.
*
- * @param $decodedData Raw raw package data array
+ * @param $packageInstance An instance of a DeliverablePackage class
* @return void
*/
- function discoverRawRecipients (array $decodedData);
+ function discoverRawRecipients (DeliverablePackage $packageInstance);
}
// Import application-specific stuff
use Org\Shipsimu\Hub\Discovery\Recipient\DiscoverableRecipient;
use Org\Shipsimu\Hub\Handler\Protocol\HandleableProtocol;
+use Org\Shipsimu\Hub\Network\Package\DeliverablePackage;
/**
* An interface for socket discovery
* Tries to discover the right socket for given package data and returns a
* matching socket resource.
*
- * @param $packageData Raw package data array
+ * @param $packageInstance An instance of a DeliverablePackage class array
* @param $connectionType Type of connection, can be either 'incoming' or 'outgoing', but *NEVER* 'server'!
* @return $socketInstance An instance of a StorableSocket class
* @throws NoListGroupException If the procol group is not found in peer list
* @throws NullPointerException If listenerInstance is NULL
*/
- function discoverSocket (array $packageData, $connectionType);
+ function discoverSocket (DeliverablePackage $packageInstance, $connectionType);
/**
* Tries to dicover the right listener instance
*
* @param $protocolInstance An instance of a HandleableProtocol class
- * @param $packageData Raw package data
+ * @param $packageInstance An instance of a DeliverablePackage class
* @return $listenerInstance An instance of a Listenable instance or null
*/
- function discoverListenerInstance (HandleableProtocol $protocolInstance, array $packageData);
+ function discoverListenerInstance (HandleableProtocol $protocolInstance, DeliverablePackage $packageInstance);
}
// Import application-specific stuff
use Org\Shipsimu\Hub\Generic\HubInterface;
+use Org\Shipsimu\Hub\Network\Package\DeliverablePackage;
/**
* An interface for DHTs
/**
* Find recipients for given package data
*
- * @param $packageData An array of valid package data
+ * @param $packageInstance An instance of a DeliverablePackage class
* @return $recipients An indexed array with DHT recipients
*/
- function findRecipientsByPackageData (array $packageData);
+ function findRecipientsByPackageData (DeliverablePackage $packageInstance);
/**
* Whether the DHT has fully bootstrapped (after state 'booting')
* @return void
*/
function enableAcceptDhtBootstrap ();
-}
-// [EOF]
-?>
+}
/**
* "Getter" for next decoded data from the stacker
*
- * @return $decodedData Raw data from the stacker
+ * @return $packageInstance An instance of a DeliverablePackage class
*/
function getNextRawData ();
// Import application-specific stuff
use Org\Shipsimu\Hub\Generic\HubInterface;
+use Org\Shipsimu\Hub\Network\Package\DeliverablePackage;
// Import framework stuff
use Org\Mxchange\CoreFramework\Handler\Handleable;
* Validates given 'recipient' if it is a valid UNL. This means that the UNL
* can be parsed by the protocol handler.
*
- * @param $packageData Valid raw package data
+ * @param $packageInstance Valid raw package data
* @return $isValid Whether the UNL can be validated
*/
- function isValidUniversalNodeLocatorByPackageData (array $packageData);
+ function isValidUniversalNodeLocatorByPackageData (DeliverablePackage $packageInstance);
/**
* If the found UNL (address) matches own external or internal address
// Import application-specific stuff
use Org\Shipsimu\Hub\Container\Socket\StorableSocket;
use Org\Shipsimu\Hub\Helper\HubHelper;
+use Org\Shipsimu\Hub\Network\Package\DeliverablePackage;
/**
* An interface for connection helper classes
/**
* Sends raw package data to the recipient
*
- * @param $packageData Raw package data
+ * @param $packageInstance An instance of a DeliverablePackage class
* @return void
* @throws InvalidSocketException If we got a problem with this socket
*/
- function sendRawPackageData (array $packageData);
+ function sendRawPackageData (DeliverablePackage $packageInstance);
/**
* Do the shutdown sequence for this connection helper
* Static "getter" for this connection class' name
*
* @param $socketInstance An instance of a StorableSocket class
- * @param $className Name of calling class
- * @return $class Expanded class name
+ * @param $className Name of calling class
+ * @return $class Expanded class name
*/
static function getConnectionClassNameFromSocket (StorableSocket $socketInstance, $className);
// Import application-specific stuff
use Org\Shipsimu\Hub\Generic\HubInterface;
+use Org\Shipsimu\Hub\Network\Package\DeliverablePackage;
/**
* An interface for listeners
/**
* Checks whether the listener would accept the given package data array
*
- * @param $packageData Raw package data
- * @return $accepts Whether this listener does accept
+ * @param $packageInstance An instance of a DeliverablePackage class
+ * @return $accepts Whether this listener does accept
*/
- function ifListenerAcceptsPackageData (array $packageData);
+ function ifListenerAcceptsPackageData (DeliverablePackage $packageInstance);
/**
* Monitors incoming raw data from the handler and transfers it to the
use Org\Shipsimu\Hub\Container\Socket\StorableSocket;
use Org\Shipsimu\Hub\Helper\Connection\ConnectionHelper;
use Org\Shipsimu\Hub\LookupTable\Lookupable;
+use Org\Shipsimu\Hub\Network\Package\DeliverablePackage;
use Org\Shipsimu\Hub\State\Peer\PeerStateable;
// Import framework stuff
/**
* Checks whether given 'sender' is a new peer
*
- * @param $packageData Raw package data
+ * @param $packageInstance An instance of a DeliverablePackage class
* @return $isNewPeer Whether 'sender' is a new peer to this node
*/
- function isSenderNewPeer (array $packageData);
+ function isSenderNewPeer (DeliverablePackage $packageInstance);
/**
* Registers a peer with given package data. We use the session id from it
*
- * @param $packageData Valid raw package data
+ * @param $packageInstance Valid An instance of a DeliverablePackage class
* @param $socketInstance An instance of a StorableSocket class
* @return void
*/
- function registerPeerByPackageData (array $packageData, StorableSocket $socketInstance);
+ function registerPeerByPackageData (DeliverablePackage $packageInstance, StorableSocket $socketInstance);
/**
- * Registers the given peer state and raw package data
+ * Registers the given peer state and An instance of a DeliverablePackage class
*
* @param $stateInstance A PeerStateable class instance
- * @param $packageData Valid package data array
+ * @param $packageInstance An instance of a DeliverablePackage class
* @return void
*/
- function registerPeerState (PeerStateable $stateInstance, array $packageData);
+ function registerPeerState (PeerStateable $stateInstance, DeliverablePackage $packageInstance);
/**
* Purges old entries of given socket resource. We use the IP address from that resource.
* Checks whether a given peer state (in helper instance) is same as stored
* in database compared with the one from $helperInstance.
*
- * @param $helperInstance An instance of a ConnectionHelper class
- * @param $packageData Valid package data array
- * @return $isSamePeerState Whether the peer's state is the same
+ * @param $helperInstance An instance of a ConnectionHelper class
+ * @param $packageInstance An instance of a DeliverablePackage class
+ * @return $isSamePeerState Whether the peer's state is the same
*/
- function isSamePeerState (ConnectionHelper $helperInstance, array $packageData);
+ function isSamePeerState (ConnectionHelper $helperInstance, DeliverablePackage $packageInstance);
}
* @return void
*/
function handleMultipleMessages ();
-}
-// [EOF]
-?>
+}
* 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
+ * @return $packageInstance An instance of a DeliverablePackage class
*/
function decodeRawContent ($rawPackageContent);
/**
* Handles decoded data for this node
*
- * @param $decodedData An array with decoded raw package data
+ * @param $packageInstance An instance of a DeliverablePackage class
* @return void
*/
- function handleRawData (array $decodedData);
+ function handleRawData (DeliverablePackage $packageInstance);
/**
* Checks whether the assembler has multiple messages pending
// Import application-specific stuff
use Org\Shipsimu\Hub\Generic\HubInterface;
+use Org\Shipsimu\Hub\Network\Package\DeliverablePackage;
/**
* An interface for a package fragmenter
* to all chunks and prepends a final hashsum chunk. It will return the
* final hash for faster processing of packages.
*
- * @param $packageData Raw package data array
+ * @param $packageInstance An instance of a DeliverablePackage instance
* @param $helperInstance An instance of a ConnectionHelper class
* @return $finalHash Final hash for faster processing
*/
- function fragmentPackageArray (array $packageData, ConnectionHelper $helperInstance);
+ function fragmentPackageArray (DeliverablePackage $packageInstance, ConnectionHelper $helperInstance);
/**
* This method gets the next chunk from the internal FIFO which should be
* the key is the chunk hash and value the raw chunk data.
*
* @param $finalHash Final hash for faster lookup
- * @return $rawDataChunk Raw package data chunk
+ * @return $rawDataChunk An instance of a DeliverablePackage class chunk
*/
function getNextRawDataChunk ($finalHash);
-}
-// [EOF]
-?>
+}
--- /dev/null
+Deny from all
--- /dev/null
+<?php
+// Own namespace
+namespace Org\Shipsimu\Hub\Network\Package;
+
+// Import application-specific stuff
+use Org\Shipsimu\Hub\Generic\HubInterface;
+
+/**
+ * An interface for package delivery boys... ;-)
+ *
+ * @author Roland Haeder <webmaster@shipsimu.org>
+ * @version 0.0.0
+ * @copyright Copyright (c) 2007, 2008 Roland Haeder, 2009 - 2018 Hub Developer Team
+ * @license GNU GPL 3.0 or any newer version
+ * @link http://www.shipsimu.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 DeliverablePackage extends HubInterface {
+
+}
// Import application-specific stuff
use Org\Shipsimu\Hub\Generic\HubInterface;
+use Org\Shipsimu\Hub\Network\Package\DeliverablePackage;
// Import framework stuff
use Org\Mxchange\CoreFramework\Lists\Listable;
* Tries to resolve given recipient into session ids or Universal Node Locator
* depending on implementation (hint: Template Method Pattern)
*
- * @param $recipient Recipient to resolve (e.g. could be a virtual recipient or direct session id)
+ * @param $recipient Recipient to resolve (e.g. could be a virtual recipient or direct session id)
* @param $listInstance An instance of a Listable class
- * @param $packageData Valid package data array
- * @return $resolved Resolved recipient or VOID if only the set list has been filled
+ * @param $packageInstance An instance of a DeliverablePackage class
+ * @return $resolved Resolved recipient or VOID if only the set list has been filled
* @throws FrameworkException Could throw different exceptions depending on implementation
*/
- function resolveRecipient ($recipient, Listable $listInstance, array $packageData);
+ function resolveRecipient ($recipient, Listable $listInstance, DeliverablePackage $packageInstance);
}
-
-// [EOF]
-?>
use Org\Shipsimu\Hub\Container\Socket\StorableSocket;
use Org\Shipsimu\Hub\Information\ShareableInfo;
use Org\Shipsimu\Hub\Listener\Listenable;
+use Org\Shipsimu\Hub\Network\Package\DeliverablePackage;
// Import framework stuff
use Org\Mxchange\CoreFramework\Registry\Registerable;
/**
* "Getter" for info instance from given package data
*
- * @param $packageData Raw package data
+ * @param $packageInstance An instance of a DeliverablePackage class
* @return $infoInstance An instance of a ShareableInfo class
*/
- function getInfoInstanceFromPackageData (array $packageData);
+ function getInfoInstanceFromPackageInstance (DeliverablePackage $packageInstance);
/**
* Checks whether a socket of a connection type 'incoming' is registered.
// Import application-specific stuff
use Org\Shipsimu\Hub\Container\Socket\StorableSocket;
use Org\Shipsimu\Hub\Helper\Connection\ConnectionHelper;
+use Org\Shipsimu\Hub\Network\Package\DeliverablePackage;
// Import framework stuff
use Org\Mxchange\CoreFramework\Resolver\Resolver;
* Returns an state instance for a given package raw data and socket resource
*
* @param $helperInstance An instance of a ConnectionHelper class
- * @param $packageData Raw package data
+ * @param $packageInstance An instance of a DeliverablePackage class
* @param $socketInstance An instance of a StorableSocket class
* @return $stateInstance An instance of the resolved state
*/
- static function resolveStateByPackage (ConnectionHelper $helperInstance, array $packageData, StorableSocket $socketInstance);
+ static function resolveStateByPackage (ConnectionHelper $helperInstance, DeliverablePackage $packageInstance, StorableSocket $socketInstance);
/**
* Checks whether the given state is valid
// Import application-specific stuff
use Org\Shipsimu\Hub\Generic\HubInterface;
+use Org\Shipsimu\Hub\Network\Package\DeliverablePackage;
/**
* An interface/tag for socket classes
/**
* "Getter" for a valid socket resource from given packae data.
*
- * @param $packageData Raw package data
+ * @param $packageInstance An instance of a DeliverablePackage class
* @param $connectionType Type of connection, can be 'incoming', 'outgoing', 'server' or default
* @return $socketInstance An instance of a StorableSocket class
* @throws InvalidConnectionTypeException If the provided connection type is not valid
*/
- function getSocketFromPackageData (array $packageData, $connectionType = NULL);
+ function getSocketFromPackageInstance (DeliverablePackage $packageInstance, $connectionType = NULL);
}
// Import application-specific stuff
use Org\Shipsimu\Hub\Generic\HubInterface;
use Org\Shipsimu\Hub\Listener\Listenable;
+use Org\Shipsimu\Hub\Network\Package\DeliverablePackage;
// Import framework stuff
/**
* Chooses the right protocol from given package data
*
- * @param $packageData Raw package data
+ * @param $packageInstance An instance of a DeliverablePackage class
* @return $protocolInstance An instance of a HandleableProtocol class
*/
- function chooseProtocolFromPackageData (array $packageData);
+ function chooseProtocolFromPackageInstance (DeliverablePackage $packageInstance);
/**
* Checks whether the given package data is accepted by the listener
*
- * @param $packageData Raw package data
+ * @param $packageInstance An instance of a DeliverablePackage class
* @param $listenerInstance A Listenable instance
- * @return $accepts Whether it is accepted
+ * @return $accepts Whether it is accepted
*/
- function ifPackageDataIsAcceptedByListener (array $packageData, Listenable $listenerInstance);
+ function ifPackageDataIsAcceptedByListener (DeliverablePackage $packageInstance, Listenable $listenerInstance);
}
-Subproject commit 1956ac6a5f89588c5cf1e10c0cbd0a14915c4646
+Subproject commit 93b7ac0613b9702427ec8314a6ef45dbfc3ea224