Exemplo n.º 1
0
        static void Forward(TcpClient source)
        {
            source.Client.Blocking = true;
            EndPoint      sourceEndPoint = source.Client.RemoteEndPoint;
            EndPoint      targetEndPoint = null;
            NetworkStream sourceStream   = source.GetStream();
            long          source2Target  = 0;
            long          target2Source  = 0;

            try
            {
                TcpClient target = GetTargetConnection();
                targetEndPoint = target.Client.RemoteEndPoint;
                NetworkStream targetStream = target.GetStream();
                Log.LogVerbose(string.Format("Establishing tunnel <cyan>{0} <default><-> <yellow>{1}", sourceEndPoint, targetEndPoint));

                #region Source2Target Task
                Task source2TargetTask = Task.Factory.StartNew(() =>
                {
                    try
                    {
                        while (source.Connected && target.Connected && 0 < sourceStream.CopyBlocksTo(targetStream, callback: (sender, e) => { source2Target += e.Part; }))
                        {
                            ;
                        }
                    }
                    catch { }
                });
                #endregion
                #region Target2Source Task
                Task target2SourceTask = Task.Factory.StartNew(() =>
                {
                    try { while (source.Connected && target.Connected && 0 < targetStream.CopyBlocksTo(sourceStream, callback: (sender, e) => { target2Source += e.Part; }))
                          {
                              ;
                          }
                    }
                    catch { }
                });
                #endregion

                Task.WaitAny(new[] { target2SourceTask, source2TargetTask });
                source.Close();
                target.Close();
            }
            catch (Exception ex)
            {
                Log.LogVerbose(StringExtensions.Format("Unclean tunnel exit at <cyan>{0} <default><-> <yellow>{1}", sourceEndPoint, targetEndPoint), ex);
            }

            {
                LogLevel level = ShowStatistics ? LogLevel.Information : LogLevel.Verbose;
                Log.Write(level, StringExtensions.Format("Tunnel <cyan>{0} <default><-> {1} <default>Source2Target: <yellow>{2} <default>Target2Source: <yellow>{3}",
                                                         sourceEndPoint, targetEndPoint, source2Target.FormatBinarySize(), target2Source.FormatBinarySize()));
            }
            {
                LogLevel level = ShowConnects ? LogLevel.Information : LogLevel.Verbose;
                Log.Write(level, string.Format("Disconnect from <cyan>{0}", sourceEndPoint));
            }
        }