/// <summary> /// Reads a protocol message from the specified byte-field and calls appropriate methods to process this message. /// </summary> /// <remarks> /// This function checks all applicable checksums and validates that the message is complete before calling one of the specialized /// methods to handle actual decoding and processing. /// </remarks> /// <param name="recv_buffer">Byte-field with an Ixian protocol message.</param> /// <param name="endpoint">Remote endpoint from where the message was received.</param> public static void readProtocolMessage(QueueMessageRaw raw_message, MessagePriority priority, RemoteEndpoint endpoint) { if (endpoint == null) { Logging.error("Endpoint was null. readProtocolMessage"); return; } ProtocolMessageCode code = raw_message.code; // Filter messages if (endpoint.presence == null) { // Check for presence and only accept hello and bye messages if there is no presence. if (code != ProtocolMessageCode.hello && code != ProtocolMessageCode.helloData && code != ProtocolMessageCode.bye) { return; } } if (raw_message.legacyChecksum != null) { // Compute checksum of received data byte[] local_checksum = Crypto.sha512sqTrunc(raw_message.data, 0, 0, 32); // Verify the checksum before proceeding if (local_checksum.SequenceEqual(raw_message.legacyChecksum) == false) { Logging.error("Dropped message (invalid legacy checksum)"); return; } } else { // Compute checksum of received data uint local_checksum = Crc32CAlgorithm.Compute(raw_message.data); // Verify the checksum before proceeding if (local_checksum != raw_message.checksum) { Logging.error("Dropped message (invalid checksum)"); return; } } // Can proceed to parse the data parameter based on the protocol message code. // Data can contain multiple elements. //parseProtocolMessage(code, data, socket, endpoint); NetworkQueue.receiveProtocolMessage(code, raw_message.data, Crc32CAlgorithm.Compute(raw_message.data), priority, endpoint); }
/// <summary> /// Reads a protocol message from the specified byte-field and calls appropriate methods to process this message. /// </summary> /// <remarks> /// This function checks all applicable checksums and validates that the message is complete before calling one of the specialized /// methods to handle actual decoding and processing. /// </remarks> /// <param name="recv_buffer">Byte-field with an Ixian protocol message.</param> /// <param name="endpoint">Remote endpoint from where the message was received.</param> public static void readProtocolMessage(byte[] recv_buffer, RemoteEndpoint endpoint) { if (endpoint == null) { Logging.error("Endpoint was null. readProtocolMessage"); return; } ProtocolMessageCode code = ProtocolMessageCode.hello; byte[] data = null; using (MemoryStream m = new MemoryStream(recv_buffer)) { using (BinaryReader reader = new BinaryReader(m)) { // Check for multi-message packets. One packet can contain multiple network messages. while (reader.BaseStream.Position < reader.BaseStream.Length) { byte[] data_checksum; try { byte startByte = reader.ReadByte(); int message_code = reader.ReadInt32(); code = (ProtocolMessageCode)message_code; int data_length = reader.ReadInt32(); // If this is a connected client, filter messages if (endpoint.GetType() == typeof(RemoteEndpoint)) { if (endpoint.presence == null) { // Check for presence and only accept hello and syncPL messages if there is no presence. if (code == ProtocolMessageCode.hello || code == ProtocolMessageCode.getPresenceList || code == ProtocolMessageCode.getBalance || code == ProtocolMessageCode.newTransaction) { } else { // Ignore anything else return; } } } data_checksum = reader.ReadBytes(32); // sha512qu, 32 bytes byte header_checksum = reader.ReadByte(); byte endByte = reader.ReadByte(); data = reader.ReadBytes(data_length); } catch (Exception e) { Logging.error(String.Format("NET: dropped packet. {0}", e)); return; } // Compute checksum of received data byte[] local_checksum = Crypto.sha512sqTrunc(data, 0, 0, 32); // Verify the checksum before proceeding if (local_checksum.SequenceEqual(data_checksum) == false) { Logging.error("Dropped message (invalid checksum)"); continue; } // Can proceed to parse the data parameter based on the protocol message code. // Data can contain multiple elements. //parseProtocolMessage(code, data, socket, endpoint); NetworkQueue.receiveProtocolMessage(code, data, data_checksum, endpoint); } } } }