protected void parseDataInternal(byte[] data, RemoteEndpoint endpoint) { QueueMessageRaw message = new QueueMessageRaw(); message.data = data; message.endpoint = endpoint; lock (recvRawQueueMessages) { recvRawQueueMessages.Add(message); } }
/// <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); }
// Parse thread protected void parseLoop() { // Prepare an special message object to use while sending, without locking up the queue messages QueueMessageRaw active_message = new QueueMessageRaw(); while (running) { TLC.Report(); try { bool message_found = false; lock (recvRawQueueMessages) { if (recvRawQueueMessages.Count > 0) { // Pick the oldest message QueueMessageRaw candidate = recvRawQueueMessages[0]; active_message.data = candidate.data; active_message.endpoint = candidate.endpoint; // Remove it from the queue recvRawQueueMessages.Remove(candidate); message_found = true; } } if (message_found) { // Active message set, add it to Network Queue CoreProtocolMessage.readProtocolMessage(active_message.data, this); } else { Thread.Sleep(10); } } catch (Exception e) { Logging.error(String.Format("Exception occured for client {0} in parseLoopRE: {1} ", getFullAddress(), e)); } // Sleep a bit to prevent cpu waste Thread.Yield(); } }