private bool m_dspExElevated = false; // If false, the connection hasn't been elevated to DSPEx yet // Note: Frame Reader owns m_reader and can access it without a lock private void FrameReaderThreadStart() { if (m_localRole == DSPExNodeRole.Server) { // Read dspex init elevation var opcode = m_reader.ReadByte(); if (opcode != (byte)DTP.DSPEX_INIT) { throw new NotSupportedException("Expected DSP_EX_INIT opcode!"); } m_dspExElevated = true; } else { m_dspExElevated = true; // performed at ctor } try { int frameProcessorRoundRobinIndex = 0; while (m_node.IsAlive && IsAlive) { var frameLength = m_reader.ReadUInt32(); // includes frameLength Logger.L(LoggerLevel.Info, "Reading DSPEx Frame of Length " + frameLength); var frameContentLength = (int)frameLength - 4; var buffer = TakeFrameBuffer(frameContentLength); // thread safe // Copy frame length to the buffer's first four bytes buffer[0] = (byte)((frameLength >> 0) & 0xFF); buffer[1] = (byte)((frameLength >> 8) & 0xFF); buffer[2] = (byte)((frameLength >> 16) & 0xFF); buffer[3] = (byte)((frameLength >> 24) & 0xFF); var bytesToRead = frameContentLength; while (bytesToRead > 0) { var bytesRead = m_reader.Read(buffer, 4 + frameContentLength - bytesToRead, bytesToRead); bytesToRead -= bytesRead; } //for (int i = 0; i < frameContentLength + 4; i++) // Console.WriteLine(i + ": " + buffer[i].ToString()); Logger.L(LoggerLevel.Info, "Sending DSPEx Frame of Length " + frameLength + " to processor"); var index = frameProcessorRoundRobinIndex; var processor = m_frameProcessors[frameProcessorRoundRobinIndex]; processor.EnqueueFrame(buffer); frameProcessorRoundRobinIndex = (index + 1) % m_frameProcessors.Length; Logger.L(LoggerLevel.Info, "Sent DSPEx Frame of Length " + frameLength + " to processor"); } } catch (EndOfStreamException e) { // end of session IsAlive = false; Console.WriteLine("Disconnected."); } }
/// <summary> /// Processes the initial echo message /// </summary> /// <param name="session"></param> /// <param name="message"></param> public override void ProcessInitialMessage(IDSPExSession session, TransactionInitialMessage message) { // Echo the message's data Logger.L(LoggerLevel.Info, "Sending echo response of length " + message.DataLength); var response = new TransactionMessage(TransactionID, message.DataBuffer, message.DataOffset, message.DataLength); session.SendMessage(response); session.DeregisterRITransactionHandler(this); }
/// <summary> /// Initializes our Locally Initialized transaction handler, sending over the initial echo /// request. /// </summary> /// <param name="session"></param> public override void InitializeInteraction(IDSPExSession session) { session.SendMessage( new TransactionInitialMessage( TransactionId, (byte)DTP.ECHO, RequestData, 0, RequestData.Length ) ); Logger.L(LoggerLevel.Info, "Sent Echo"); }
// Note: Frame Writer owns m_writer and can access it without a lock private void FrameWriterThreadStart() { while (m_node.IsAlive && IsAlive) { // used byte shifting rather than binaryreader/fixed as this is a fairly simple op... var buffer = m_frameBuffersToSend.Take(); // Note: Buffer length != frame length!!! int frameLength = buffer[0] | (buffer[1] << 8) | (buffer[2] << 16) | (buffer[3] << 24); Logger.L(LoggerLevel.Info, "Writing DSPEx Frame of Length " + frameLength); m_writer.Write(buffer, 0, frameLength); Logger.L(LoggerLevel.Info, "Wrote DSPEx Frame of Length " + frameLength); ReturnFrameBuffer(buffer); } }
private void ServerThreadStart(CountdownEvent signalledOnWaitingForConnection) { while (m_isAlive) { var pipeHandle = LowIntegrityPipeFactory.CreateLowIntegrityNamedPipe(m_defaultPipeName); var connection = new NamedPipeServerStream(PipeDirection.InOut, true, false, pipeHandle); if (signalledOnWaitingForConnection != null) { signalledOnWaitingForConnection.Signal(); signalledOnWaitingForConnection = null; } connection.WaitForConnection(); Logger.L(LoggerLevel.Info, "DSPEx Node got connection"); var session = new DtpNodeSession(this, connection, DSPExNodeRole.Server); m_sessions.TryAdd(session); } }
/// <summary> /// Processes the response to our LIT Handler. The data segment of the message should be /// identical to our request data, as this is an echo implementation. /// </summary> /// <param name="session"></param> /// <param name="message"></param> public unsafe override void ProcessMessage(IDSPExSession session, TransactionMessage message) { bool match = RequestData.Length == message.DataLength; //if (match) //{ // fixed (byte* pRequestBuffer = RequestData) // fixed (byte* pResponseBuffer = message.DataBuffer) // { // byte* pResponseBuffer_ = pResponseBuffer + message.DataOffset; // match = memcmp(pRequestBuffer, pResponseBuffer_, RequestData.Length) == 0; // } //} ResponseDataMatched = match; session.DeregisterLITransactionHandler(this); OnCompletion(); Logger.L(LoggerLevel.Info, "Echo response matched? " + match); }
protected override void ThreadStart(CountdownEvent readySignal) { try { while (!CancellationToken.IsCancellationRequested) { var pipeHandle = LowIntegrityPipeFactory.CreateLowIntegrityNamedPipe(pipeName); var connection = new NamedPipeServerStream(PipeDirection.InOut, true, false, pipeHandle); if (readySignal != null) { readySignal.Signal(); readySignal = null; } var asyncResult = connection.BeginWaitForConnection(ar => acceptThreadSynchronization.Release(1), null); acceptThreadSynchronization.WaitOne(); Console.WriteLine("Past acceptThreadSynchronization!"); if (asyncResult.IsCompleted) { connection.EndWaitForConnection(asyncResult); Logger.L(LoggerLevel.Info, "DSPEx Node got connection"); HandleAccept(connection); } else { connection.Dispose(); pipeHandle.Dispose(); } } } finally { if (readySignal != null) { readySignal.Signal(); } } }
private void ThreadStart() { var id = Thread.CurrentThread.ManagedThreadId; while (m_node.IsAlive && m_session.IsAlive) { if (!m_semaphore.WaitOne(10000)) { continue; } byte[] assignedFrame = null; while (!m_frameQueue.TryDequeue(out assignedFrame)) { ; } Logger.L(LoggerLevel.Info, "Frame Processor " + id + " got frame of buffer size " + assignedFrame.Length); using (var ms = new MemoryStream(assignedFrame)) using (var reader = new BinaryReader(ms)) { UInt32 frameSize = reader.ReadUInt32(); UInt32 transactionId = reader.ReadUInt32(); Logger.L(LoggerLevel.Info, " => Frame Size: " + frameSize); bool isLit = m_session.IsLocallyInitializedTransaction(transactionId); Logger.L(LoggerLevel.Info, " => Is LIT?: " + isLit); if (isLit) { var handler = m_session.GetLocallyInitializedTransactionHandler(transactionId); if (handler == null) { throw new KeyNotFoundException("Referenced nonexistent LIT " + transactionId); } handler.ProcessMessage( m_session, new TransactionMessage( transactionId, assignedFrame, 8, (int)(frameSize - 8) ) ); } else // riTransaction: { var opcode = frameSize > 8 ? assignedFrame[8] : (byte)0; // GoCRITH returns true if the handler was created, false if it existed var handler = m_session.GetRemotelyInitializedTransactionHandler(transactionId, opcode); if (handler == null) { Logger.L(LoggerLevel.Info, " => Handler Nonexistant! Opcode: " + opcode); handler = m_session.CreateAndRegisterRITransactionHandler(transactionId, opcode); handler.ProcessInitialMessage( m_session, new TransactionInitialMessage( transactionId, opcode, assignedFrame, 9, (int)(frameSize - 9) ) ); } else { Logger.L(LoggerLevel.Info, " => Handler Existant!"); handler.ProcessMessage( m_session, new TransactionMessage( transactionId, assignedFrame, 8, (int)(frameSize - 8) ) ); } } }// using m_onFrameProcessed(this, assignedFrame); } // while }