public ProxyConnection(TcpClient inboundClient, IPEndPoint outboundEndPoint, ConnectionMode inboundMode, ConnectionMode outboundMode, uint bufferSize, string certificateName, bool dumpTraffic, string targetHost) { _closeEvent = new AutoResetEvent(true); _certificate = certificateName; _inboundMode = inboundMode; _outboundMode = outboundMode; _inboundBuffer = new byte[bufferSize]; _outboundBuffer = new byte[bufferSize]; _dumpTraffic = dumpTraffic; _targetHost = targetHost; _inboundClient = inboundClient; _inboundEndPoint = _inboundClient.Client.RemoteEndPoint; InboundConnectionState = ProxyConnectionState.Open; Log.InfoFormat("Accepted {0} connection from {1}.", _inboundMode, inboundClient.Client.RemoteEndPoint); OutboundConnectionState = ProxyConnectionState.Closed; _outboundEndPoint = outboundEndPoint; _outboundClient = new TcpClient(); Run(outboundEndPoint); }
public void Close() { if (InboundConnectionState == ProxyConnectionState.Closed && OutboundConnectionState == ProxyConnectionState.Closed) { return; } Log.Info("Closing proxy connection..."); _closeEvent.WaitOne(); if (InboundConnectionState != ProxyConnectionState.Closed) { InboundConnectionState = ProxyConnectionState.PendingClose; _inboundClient.Close(); InboundConnectionState = ProxyConnectionState.Closed; Log.InfoFormat("{0} connection from {1} is closed.", _inboundMode, _inboundEndPoint); } if (OutboundConnectionState != ProxyConnectionState.Closed) { OutboundConnectionState = ProxyConnectionState.PendingClose; _outboundClient.Close(); OutboundConnectionState = ProxyConnectionState.Closed; Log.InfoFormat("{0} connection to {1} is closed.", _outboundMode, _outboundEndPoint); OnClosed(this, new EventArgs()); } }
private void Run(IPEndPoint outboundEndPoint) { var runTask = new Task(async() => { using (LogicalThreadContext.Stacks["connectionID"].Push(Guid.NewGuid().ToString())) { OutboundConnectionState = ProxyConnectionState.PendingOpen; try { await _outboundClient.ConnectAsync(outboundEndPoint.Address, outboundEndPoint.Port); } catch (Exception ex) { Log.Error(String.Format("Failed to connect to {0}.", outboundEndPoint), ex); Close(); return; } OutboundConnectionState = ProxyConnectionState.Open; Log.InfoFormat("Open {0} connection to {1}.", _outboundMode, outboundEndPoint); Stream sourceStream; try { sourceStream = await GetStream(_inboundClient.GetStream(), _inboundMode, true, _targetHost); Log.DebugFormat("Inbound connection from {0} to {1} established.", _inboundEndPoint, _outboundEndPoint); } catch (IOException ex) { Log.Error( String.Format("Failed to establish inbound connection from {0} to {1} due to commnunication error.", _inboundEndPoint, _outboundEndPoint), ex); Close(); return; } catch (ObjectDisposedException ex) { Close(); return; } catch (Exception ex) { Log.Error( String.Format("Failed to establish inbound connection from {0} to {1} due to unhandled exception.", _inboundEndPoint, _outboundEndPoint), ex); Close(); return; } Stream destinationStream; try { destinationStream = await GetStream(_outboundClient.GetStream(), _outboundMode, false, _targetHost); Log.DebugFormat("Outbound connection from {0} to {1} established.", _inboundEndPoint, _outboundEndPoint); } catch (IOException ex) { Log.Error( String.Format("Failed to establish outbound connection from {0} to {1}.", _inboundEndPoint, _outboundEndPoint), ex); Close(); return; } catch (Exception ex) { Log.Error("Unhandled exception.", ex); Close(); return; } var inboundRun = RunConnection(sourceStream, destinationStream, _inboundBuffer, _inboundEndPoint, _outboundEndPoint, _inboundMode, _outboundMode); var outboundRun = RunConnection(destinationStream, sourceStream, _outboundBuffer, _outboundEndPoint, _inboundEndPoint, _outboundMode, _inboundMode); Task.WaitAll(inboundRun, outboundRun); } }); runTask.Start(); }