public void Start() { if (_state != TcpActorState.NotStarted) { throw new InvalidOperationException(string.Format("The actor must have the state 'NotStarted' when calling Start. State {0} is not valid.", _state)); } _state = TcpActorState.Running; lock (_syncRoot) { _connectionIndex = _connectionCounter; _connectionCounter++; } _engineTask = new Task(Engine); _engineTask.Start(); }
public void Stop() { if (_state != TcpActorState.Stopped) { return; } if (_state != TcpActorState.RequestStop && _state != TcpActorState.Running) { throw new InvalidOperationException(string.Format("The actor must have the state 'RequestStop' or 'Running' when calling Stop. State {0} is not valid.", _state)); } _state = TcpActorState.Stopped; _fromClientTask.Dispose(); _fromTargetTask.Dispose(); _tcpClientActor.Stop(); if (_tcpTargetActor != null) { _tcpTargetActor.Stop(); } OnTcpActorStoppedEvent(new TcpActorStoppedEventArgs(this)); }
public void Start() { if (_state != TcpActorState.NotStarted) throw new InvalidOperationException(string.Format("The actor must have the state 'NotStarted' when calling Start. State {0} is not valid.", _state)); _state = TcpActorState.Running; lock (_syncRoot) { _connectionIndex = _connectionCounter; _connectionCounter++; } _engineTask = new Task(Engine); _engineTask.Start(); }
private void FromTargetToClient() { try { //Wait for response while (_state == TcpActorState.Running && _tcpTargetActor == null && _staticResponse == null) { LogHelper.ShowMessage(string.Format("Connection {0} is waiting for information about the internal target.", _connectionIndex)); _targetRecievedEvent.WaitOne(); } if (_tcpTargetActor != null) { LogHelper.ShowMessage(string.Format("Connection {0} started to transfer data. ({1}:{2} --> {3}:{4})", _connectionIndex, string.IsNullOrEmpty(_currentRedirectRule.PublicRequestHost) ? "'Any'" : _currentRedirectRule.PublicRequestHost, _currentRedirectRule.PublicRequestPort, _currentRedirectRule.InternalTargetAddress, _currentRedirectRule.InternalTargetPort)); var messageChunk = new byte[MessageChunkSize]; while (_state == TcpActorState.Running) { var bytesRead = 0; try { bytesRead = _tcpTargetActor.Read(messageChunk, 0, messageChunk.Length); PerformaceCounters.Instance.Tx(bytesRead); _totalTx += bytesRead; } catch (System.IO.IOException exp) { //Expected when the server closes //exp = {"Unable to read data from the transport connection: An existing connection was forcibly closed by the remote host."} //Console.WriteLine("{0}. [Swallow] {1}", _connectionIndex, exp.Message); LogHelper.LogException(exp, false, LogHelper.ExceptionSeverity.InformationException); } if (bytesRead > 0) _tcpClientActor.Write(messageChunk, 0, bytesRead); //TODO: Here is the place to log throughput from server back to client. At this point response data has been transferred from the target back to the client. } } else if (!string.IsNullOrEmpty(_staticResponse)) { _fromClientTask.Wait(); //Wait until the reader have completed _tcpClientActor.Write(_staticResponse); LogHelper.ShowMessage(string.Format("Connection {0} returned a static response. ({1})", _connectionIndex, _staticResponse)); PerformaceCounters.Instance.Tx(_staticResponse.Length); _totalTx += _staticResponse.Length; } else { //In this case, just close the connection LogHelper.LogMessage("There is no target actor to send back a response to, and no static response.", Issue.IssueLevel.Warning); } } catch (System.IO.IOException exp) { //Expected when the client closes. //exp = {"Unable to write data to the transport connection: An established connection was aborted by the software in your host machine."} LogHelper.LogException(exp,false, LogHelper.ExceptionSeverity.InformationException); } catch (Exception exp) { LogHelper.LogException(exp, false, LogHelper.ExceptionSeverity.ErrorException); throw; } finally { _state = TcpActorState.RequestStop; LogHelper.ShowMessage(string.Format("Connection {0} stopped to transfer data. (Tx: {1})", _connectionIndex, _totalTx)); } }
private void FromClientToTarget() { try { LogHelper.ShowMessage(string.Format("Connection {0} started to read.", _connectionIndex)); var messageChunk = new byte[MessageChunkSize]; while (_state == TcpActorState.Running) { var bytesRead = _tcpClientActor.Read(messageChunk, 0, messageChunk.Length); PerformaceCounters.Instance.Rx(bytesRead); _totalRx += bytesRead; //If there is no _tcpTargetActor, try to get one. if (_tcpTargetActor == null) { _currentRedirectRule = GetTargetInfo(messageChunk, bytesRead); if (_currentRedirectRule != null) _tcpTargetActor = new TcpClientActor(new TcpClient(_currentRedirectRule.InternalTargetAddress.ToString(), _currentRedirectRule.InternalTargetPort)); _targetRecievedEvent.Set(); } if (_tcpTargetActor == null) { //If there still is no target actor, exit the loop. LogHelper.LogMessage("The reader could not find a target actor to forward the traffic to.", Issue.IssueLevel.Warning); break; } _tcpTargetActor.Write(messageChunk, 0, bytesRead); //TODO: Here is the place to log throughput from client to server. At this point data has been transferred from the client to the target. } } catch (System.IO.IOException exp) { //Expected when the client closes. //exp = {"Unable to read data from the transport connection: An existing connection was forcibly closed by the remote host."} LogHelper.LogException(exp, false, LogHelper.ExceptionSeverity.InformationException); } catch (ObjectDisposedException exp) { LogHelper.LogException(exp, false, LogHelper.ExceptionSeverity.ErrorException); } catch (InvalidOperationException exp) { LogHelper.LogException(exp, false, LogHelper.ExceptionSeverity.ErrorException); } catch (SocketException exp) { //Expected when there is no server listening. LogHelper.LogException(exp, true, LogHelper.ExceptionSeverity.WarningException); _staticResponse = exp.Message; //This message is sent back as response to the client _targetRecievedEvent.Set(); } catch (Exception exp) { LogHelper.LogException(exp, false, LogHelper.ExceptionSeverity.ErrorException); throw; } finally { _state = TcpActorState.RequestStop; LogHelper.ShowMessage(string.Format("Connection {0} stopped to read. (Rx: {1})", _connectionIndex, _totalRx)); } }
public void Stop() { if (_state != TcpActorState.Stopped) return; if (_state != TcpActorState.RequestStop && _state != TcpActorState.Running) throw new InvalidOperationException(string.Format("The actor must have the state 'RequestStop' or 'Running' when calling Stop. State {0} is not valid.", _state)); _state = TcpActorState.Stopped; _fromClientTask.Dispose(); _fromTargetTask.Dispose(); _tcpClientActor.Stop(); if (_tcpTargetActor != null) _tcpTargetActor.Stop(); OnTcpActorStoppedEvent(new TcpActorStoppedEventArgs(this)); }
private void FromTargetToClient() { try { //Wait for response while (_state == TcpActorState.Running && _tcpTargetActor == null && _staticResponse == null) { LogHelper.ShowMessage(string.Format("Connection {0} is waiting for information about the internal target.", _connectionIndex)); _targetRecievedEvent.WaitOne(); } if (_tcpTargetActor != null) { LogHelper.ShowMessage(string.Format("Connection {0} started to transfer data. ({1}:{2} --> {3}:{4})", _connectionIndex, string.IsNullOrEmpty(_currentRedirectRule.PublicRequestHost) ? "'Any'" : _currentRedirectRule.PublicRequestHost, _currentRedirectRule.PublicRequestPort, _currentRedirectRule.InternalTargetAddress, _currentRedirectRule.InternalTargetPort)); var messageChunk = new byte[MessageChunkSize]; while (_state == TcpActorState.Running) { var bytesRead = 0; try { bytesRead = _tcpTargetActor.Read(messageChunk, 0, messageChunk.Length); PerformaceCounters.Instance.Tx(bytesRead); _totalTx += bytesRead; } catch (System.IO.IOException exp) { //Expected when the server closes //exp = {"Unable to read data from the transport connection: An existing connection was forcibly closed by the remote host."} //Console.WriteLine("{0}. [Swallow] {1}", _connectionIndex, exp.Message); LogHelper.LogException(exp, false, LogHelper.ExceptionSeverity.InformationException); } if (bytesRead > 0) { _tcpClientActor.Write(messageChunk, 0, bytesRead); } //TODO: Here is the place to log throughput from server back to client. At this point response data has been transferred from the target back to the client. } } else if (!string.IsNullOrEmpty(_staticResponse)) { _fromClientTask.Wait(); //Wait until the reader have completed _tcpClientActor.Write(_staticResponse); LogHelper.ShowMessage(string.Format("Connection {0} returned a static response. ({1})", _connectionIndex, _staticResponse)); PerformaceCounters.Instance.Tx(_staticResponse.Length); _totalTx += _staticResponse.Length; } else { //In this case, just close the connection LogHelper.LogMessage("There is no target actor to send back a response to, and no static response.", Issue.IssueLevel.Warning); } } catch (System.IO.IOException exp) { //Expected when the client closes. //exp = {"Unable to write data to the transport connection: An established connection was aborted by the software in your host machine."} LogHelper.LogException(exp, false, LogHelper.ExceptionSeverity.InformationException); } catch (Exception exp) { LogHelper.LogException(exp, false, LogHelper.ExceptionSeverity.ErrorException); throw; } finally { _state = TcpActorState.RequestStop; LogHelper.ShowMessage(string.Format("Connection {0} stopped to transfer data. (Tx: {1})", _connectionIndex, _totalTx)); } }
private void FromClientToTarget() { try { LogHelper.ShowMessage(string.Format("Connection {0} started to read.", _connectionIndex)); var messageChunk = new byte[MessageChunkSize]; while (_state == TcpActorState.Running) { var bytesRead = _tcpClientActor.Read(messageChunk, 0, messageChunk.Length); PerformaceCounters.Instance.Rx(bytesRead); _totalRx += bytesRead; //If there is no _tcpTargetActor, try to get one. if (_tcpTargetActor == null) { _currentRedirectRule = GetTargetInfo(messageChunk, bytesRead); if (_currentRedirectRule != null) { _tcpTargetActor = new TcpClientActor(new TcpClient(_currentRedirectRule.InternalTargetAddress.ToString(), _currentRedirectRule.InternalTargetPort)); } _targetRecievedEvent.Set(); } if (_tcpTargetActor == null) { //If there still is no target actor, exit the loop. LogHelper.LogMessage("The reader could not find a target actor to forward the traffic to.", Issue.IssueLevel.Warning); break; } _tcpTargetActor.Write(messageChunk, 0, bytesRead); //TODO: Here is the place to log throughput from client to server. At this point data has been transferred from the client to the target. } } catch (System.IO.IOException exp) { //Expected when the client closes. //exp = {"Unable to read data from the transport connection: An existing connection was forcibly closed by the remote host."} LogHelper.LogException(exp, false, LogHelper.ExceptionSeverity.InformationException); } catch (ObjectDisposedException exp) { LogHelper.LogException(exp, false, LogHelper.ExceptionSeverity.ErrorException); } catch (InvalidOperationException exp) { LogHelper.LogException(exp, false, LogHelper.ExceptionSeverity.ErrorException); } catch (SocketException exp) { //Expected when there is no server listening. LogHelper.LogException(exp, true, LogHelper.ExceptionSeverity.WarningException); _staticResponse = exp.Message; //This message is sent back as response to the client _targetRecievedEvent.Set(); } catch (Exception exp) { LogHelper.LogException(exp, false, LogHelper.ExceptionSeverity.ErrorException); throw; } finally { _state = TcpActorState.RequestStop; LogHelper.ShowMessage(string.Format("Connection {0} stopped to read. (Rx: {1})", _connectionIndex, _totalRx)); } }