const EXCEPTION_BASE64_ENCODING_NOT_MODULO_4 = 0x905;
const EXCEPTION_NODE_SESSION_ID_NOT_VERIFYING = 0x906;
const EXCEPTION_REQUEST_NOT_ACCEPTED = 0x907;
- const SOCKET_ERROR_CONNECTION_RESET_BY_PEER = 0x908;
+ const EXCEPTION_DHT_BOOTSTRAP_NOT_ACCEPTED = 0x908;
+ const SOCKET_ERROR_CONNECTION_RESET_BY_PEER = 0x909;
// Message status codes
const MESSAGE_STATUS_CODE_OKAY = 'OKAY';
* @return void
*/
private function verifyChunkSerialNumbers () {
+ // Debug message
+ //* NOISY-DEBUG */ self::createDebugInstance(__CLASS__)->debugOutput('CHUNK-HANDLER[' . __METHOD__ . ':' . __LINE__ . ']: finalPackageChunks=' . print_r($this->finalPackageChunks, TRUE));
+
+ // Get final hash
+ $finalHash = $this->generateFinalHash(implode('', $this->finalPackageChunks['content']));
+
// Reset the serial number generator
- $this->getFragmenterInstance()->resetSerialNumber();
+ $this->getFragmenterInstance()->resetSerialNumber($finalHash);
// "Walk" through all (content) chunks
foreach ($this->finalPackageChunks['content'] as $serialNumber => $content) {
// Get next serial number
- $nextSerial = $this->getFragmenterInstance()->getNextHexSerialNumber();
+ $nextSerial = $this->getFragmenterInstance()->getNextHexSerialNumber($finalHash);
// Debug output
//* NOISY-DEBUG */ self::createDebugInstance(__CLASS__)->debugOutput('CHUNK-HANDLER[' . __METHOD__ . ':' . __LINE__ . ']: serialNumber=' . $serialNumber . ',nextSerial=' . $nextSerial);
assert(isset($this->finalPackageChunks['hashes'][$serialNumber]));
// Debug message
- /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('CHUNK-HANDLER[' . __METHOD__ . ':' . __LINE__ . ']: serialNumber=' . $serialNumber . ',hashes=' . $this->finalPackageChunks['hashes'][$serialNumber] . ' - validating ...');
- /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('finalPackageChunks=' . print_r($this->finalPackageChunks, TRUE) . 'chunkHashes=' . print_r($this->chunkHashes, TRUE));
+ //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('CHUNK-HANDLER[' . __METHOD__ . ':' . __LINE__ . ']: serialNumber=' . $serialNumber . ',hashes=' . $this->finalPackageChunks['hashes'][$serialNumber] . ' - validating ...');
+ //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('finalPackageChunks=' . print_r($this->finalPackageChunks, TRUE) . 'chunkHashes=' . print_r($this->chunkHashes, TRUE));
// Is this chunk valid? This should be the case
assert($this->isChunkHashValid(array(
assert($this->eopChunk[1] == $this->chunkHashes[count($this->chunkHashes) - 2]);
}
+ /**
+ * Generate final hash if EOP chunk is found, else an assert will happen.
+ *
+ * @param $rawPackageData Raw package data
+ * @return $finalHash Final hash if EOP chunk is found
+ */
+ private function generateFinalHash ($rawPackageData) {
+ // Make sure the raw package data is given
+ assert((is_string($rawPackageData)) && (!empty($rawPackageData)));
+
+ // Make sure the EOP chunk is set
+ assert((isset($this->eopChunk[0])) && (isset($this->eopChunk[1])));
+ assert((is_string($this->eopChunk[0])) && (!empty($this->eopChunk[0])));
+
+ // Hash the raw data
+ $finalHash = $this->getCryptoInstance()->hashString($rawPackageData, $this->eopChunk[0], FALSE);
+
+ // Return it
+ return $finalHash;
+ }
+
/**
* Verifies the finally assembled raw package data by comparing it against
* the final hash.
* @return void
*/
private function verifyRawPackageData () {
- // Hash the raw package data for final verification
- $finalHash = $this->getCryptoInstance()->hashString($this->rawPackageData, $this->eopChunk[0], FALSE);
+ // Generate final hash
+ $finalHash = $this->generateFinalHash($this->rawPackageData);
// Is it the same?
//* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('CHUNK-HANDLER[' . __METHOD__ . ':' . __LINE__ . ']: eopChunk[1]=' . $this->eopChunk[1] . ',finalHash=' . $finalHash);
* @return $chunkData Raw data chunk
*/
private function getRawDataFromPackageArray (array $packageData) {
- // Implode the package data array and fragement the resulting string, returns the final hash
- $finalHash = $this->getFragmenterInstance()->fragmentPackageArray($packageData, $this);
- if ($finalHash !== TRUE) {
- // Debug message
- /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('CONNECTION-HELPER[' . __METHOD__ . ':' . __LINE__ . ']: Setting finalHash=' . $finalHash . ',currentFinalHash[' . gettype($this->currentFinalHash) . ']=' . $this->currentFinalHash);
-
- // Set final hash
- $this->currentFinalHash = $finalHash;
- } // END - if
-
// Debug message
//* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('CONNECTION-HELPER[' . __METHOD__ . ':' . __LINE__ . ']: currentFinalHash=' . $this->currentFinalHash);
+ // Make sure the final hash is set
+ assert((is_string($this->currentFinalHash)) && (!empty($this->currentFinalHash)));
+
// Get the next raw data chunk from the fragmenter
$rawDataChunk = $this->getFragmenterInstance()->getNextRawDataChunk($this->currentFinalHash);
+ // Debug message
+ //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('CONNECTION-HELPER[' . __METHOD__ . ':' . __LINE__ . ']: rawDataChunk=' . print_r($rawDataChunk, TRUE));
+
// Get chunk hashes and chunk data
$chunkHashes = array_keys($rawDataChunk);
$chunkData = array_values($rawDataChunk);
// The helper's state must be 'connected'
$this->getStateInstance()->validatePeerStateConnected();
+ // Implode the package data array and fragement the resulting string, returns the final hash
+ $finalHash = $this->getFragmenterInstance()->fragmentPackageArray($packageData, $this);
+ if ($finalHash !== TRUE) {
+ // Debug message
+ //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('CONNECTION-HELPER[' . __METHOD__ . ':' . __LINE__ . ']: Setting finalHash=' . $finalHash . ',currentFinalHash[' . gettype($this->currentFinalHash) . ']=' . $this->currentFinalHash);
+
+ // Set final hash
+ $this->currentFinalHash = $finalHash;
+ } // END - if
+
// Reset serial number
- $this->getFragmenterInstance()->resetSerialNumber();
+ $this->getFragmenterInstance()->resetSerialNumber($this->currentFinalHash);
// Cache buffer length
$bufferSize = $this->getConfigInstance()->getConfigEntry($this->getProtocol() . '_buffer_length');
private $processedPackages = array();
/**
- * Serial number
+ * Serial numbers (array key is final hash)
*/
- private $serialNumber = 0x00000000;
+ private $serialNumber = array();
/**
* Maximum possible serial number, "cache" for speeding up things
// Prepend the hash to the chunk
$rawData = (
$rawDataHash . self::CHUNK_DATA_HASH_SEPARATOR .
- $this->getNextHexSerialNumber() . self::CHUNK_DATA_HASH_SEPARATOR .
+ $this->getNextHexSerialNumber($finalHash) . self::CHUNK_DATA_HASH_SEPARATOR .
$chunkData . self::CHUNK_SEPARATOR
);
/**
* "Getter" for the next hexadecimal-encoded serial number
*
+ * @param $finalHash Final hash
* @return $encodedSerialNumber The next hexadecimal-encoded serial number
*/
- public function getNextHexSerialNumber () {
+ public function getNextHexSerialNumber ($finalHash) {
// Assert on maximum serial number length
- assert($this->serialNumber <= $this->maxSerialNumber);
+ assert($this->serialNumber[$finalHash] <= $this->maxSerialNumber);
// Encode the current serial number
- /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput(__METHOD__ . ': serialNumber=' . $this->serialNumber);
- $encodedSerialNumber = $this->dec2Hex($this->serialNumber, self::MAX_SERIAL_LENGTH);
+ /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput(__METHOD__ . ': serialNumber[' . $finalHash . ']=' . $this->serialNumber[$finalHash]);
+ $encodedSerialNumber = $this->dec2Hex($this->serialNumber[$finalHash], self::MAX_SERIAL_LENGTH);
// Count one up
- $this->serialNumber++;
+ $this->serialNumber[$finalHash]++;
// Return the encoded serial number
/* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput(__METHOD__ . ': encodedSerialNumber=' . $encodedSerialNumber);
// Remember it
$this->processedPackages[$this->getProcessedPackagesIndex($packageData)] = $finalHash;
- // Init pointer
+ // Init pointer and reset serial number
$this->initPointer($finalHash);
+ $this->resetSerialNumber($finalHash);
// Split the encoded data into smaller chunks
$this->splitEncodedDataIntoChunks($rawData, $finalHash);
}
/**
- * Resets the serial number to zero
+ * Resets the serial number to zero for given final hash
*
+ * @param $finalHash Final hash to reset counter for
* @return void
*/
- public function resetSerialNumber () {
- // Debug message
- //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('FRAGMENTER: Resetting serial number, previous=' . $this->serialNumber);
+ public function resetSerialNumber ($finalHash) {
+ // Final hash must be set
+ assert((is_string($finalHash)) && (!empty($finalHash)));
// Reset serial number
- $this->serialNumber = 0;
+ $this->serialNumber[$finalHash] = 0;
}
}
-Subproject commit c68ca324e84a3297fb811ae9356f41a82b3c45ab
+Subproject commit 6807d3268e4f233bf224155956ef6858925b58b0