Beispiel #1
0
        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);
        }
Beispiel #2
0
        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());
            }
        }
Beispiel #3
0
        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();
        }