Beispiel #1
0
        public override async void OnNewConnection(TcpClient client)
        {
            var stream = GetMyStreamFromSocket(client.Client);

            try {
                var bs = BufferPool.GlobalGetBs(8 * 1024, false);
                var r  = await stream.ReadAsyncR(bs);

                if (r <= 0)
                {
                    return;
                }
                bs.Len = r;
                var ch = new TlsStream.ClientHello();
                TlsStream.ParseClientHelloRecord(bs, ref ch, out _);
                if (ch.Sni == null)
                {
                    return;
                }
                var conn = InConnectionTcp.Create(this, new AddrPort(ch.Sni, dest_port), new MyStreamWrapper(stream)
                {
                    Queue = bs
                });
                await HandleIncommingConnection(conn);
            } catch (Exception e) {
                Logger.exception(e, Logging.Level.Error, "OnNewConnection");
            } finally {
                MyStream.CloseWithTimeout(stream).Forget();
            }
        }
Beispiel #2
0
        public override async Task <ConnectResult> ProtectedConnect(ConnectArgument arg)
        {
            var dest       = arg.Dest;
            var baseResult = await ConnectHelper.Connect(this, server.WithDefaultPort(80), connect_timeout);

            if (!baseResult.Ok)
            {
                return(baseResult);
            }
            try {
                var dataStream = baseResult.Stream;
                var asStream   = MyStream.ToStream(dataStream);
                var sw         = new StringWriter(new StringBuilder(1024));
                var destStr    = dest.ToString();
                HttpClient.WriteHttpRequestHeader(sw, "CONNECT", destStr, new Dictionary <string, string> {
                    ["Host"] = destStr
                });
                await dataStream.WriteAsync(NaiveUtils.GetUTF8Bytes(sw.ToString()));

                var responseStr = await NaiveUtils.ReadStringUntil(asStream, NaiveUtils.DoubleCRLFBytes);

                var sr       = new StringReader(responseStr);
                var response = HttpClient.ReadHttpResponseHeader(sr);
                if (response.StatusCode != "200")
                {
                    throw new Exception($"remote server response '{response.StatusCode} {response.ReasonPhrase}'");
                }
                return(CreateConnectResultWithStream(dataStream));
            } catch (Exception) {
                MyStream.CloseWithTimeout(baseResult.Stream);
                throw;
            }
        }
Beispiel #3
0
        public override async Task HandleTcpConnection(InConnectionTcp connection)
        {
            Exception     e             = null;
            ConnectResult connectResult = null;

            try {
                connectResult = await Connect(connection);
            } catch (Exception ex) when(if_failed != null)
            {
                Logging.exception(ex, Logging.Level.Error, $"{this}: {connection} failed ({connectResult.FailedReason}), redirecting to {if_failed}.");
                connection.RedirectTo(if_failed);
                return;
            }
            if (!connectResult.Ok && if_failed != null)
            {
                Logging.warning($": {connection} failed ({connectResult.FailedReason}), redirecting to {if_failed}.");
                connection.RedirectTo(if_failed);
                return;
            }
            try {
                if (connectResult.Ok)
                {
                    await connection.HandleAndPutStream(this, connectResult.Stream, connectResult.WhenCanRead);
                }
                else
                {
                    await connection.HandleAndGetStream(connectResult);
                }
            } finally {
                if (connectResult.Ok)
                {
                    MyStream.CloseWithTimeout(connectResult.Stream);
                }
            }
        }
Beispiel #4
0
        protected override Task OnFinish()
        {
            var dataStream = DataStream;

            if (dataStream != null)
            {
                MyStream.CloseWithTimeout(dataStream).Forget();
            }
            return(base.OnFinish());
        }
Beispiel #5
0
            public async Task Run()
            {
                var       left              = Left;
                var       right             = Right;
                int       halfCloseTimeout  = (10 * 1000) + NaiveUtils.Random.Next(-1000, 1000);
                const int forceCloseTimeout = 10 * 1000;

                try {
                    var readFromRight = CopierFromRight.CopyAndShutdown();
                    var readFromLeft  = CopierFromLeft.CopyAndShutdown();
                    var tasks         = new Task[] { readFromRight, readFromLeft };
                    string stringFromTask(Task t) => t == readFromRight ? $"{right} -> {left}" : $"{left} -> {right}";

                    // waiting for half closing.
                    var compeletedTask = await Task.WhenAny(tasks).CAF();

                    if (compeletedTask.IsFaulted)
                    {
                        var exception = compeletedTask.Exception.InnerException;
                        Logger?.exception(exception, Logging.Level.Warning, $"stream copying exception, force closing. ({stringFromTask(compeletedTask)})");
                        return;
                    }

                    var anotherTask = compeletedTask == readFromRight ? readFromLeft : readFromRight;
                    // waiting for full closing with timeout.
                    if (await anotherTask.WithTimeout(halfCloseTimeout))
                    {
                        Logger?.warning($"keeping half closed for {halfCloseTimeout} ms, force closing. ({stringFromTask(anotherTask)})");
                    }
                    else
                    {
                        if (anotherTask.IsFaulted)
                        {
                            Logger?.exception(anotherTask.Exception.InnerException, Logging.Level.Warning, $"half closed waiting exception. {stringFromTask(anotherTask)}");
                        }
                    }
                } catch (Exception e) {
                    Logger?.exception(e, Logging.Level.Error, $"Relay task ({left.SafeToStr()} <-> {right.SafeToStr()})");
                } finally {
                    var t1 = MyStream.CloseWithTimeout(left, forceCloseTimeout);
                    var t2 = MyStream.CloseWithTimeout(right, forceCloseTimeout);
                    //await t1; await t2;
                }
            }
Beispiel #6
0
        public override void Stop()
        {
            base.Stop();
            var stream = DataStream;

            if (stream == null)
            {
                stream = ConnectResult.Stream;
            }
            if (stream == null)
            {
                Controller.Logger.warning(this + ": Can not get the stream, failed to stop.");
            }
            else
            {
                Controller.Logger.info("Closing stream " + stream + " to stop connection " + this);
                MyStream.CloseWithTimeout(stream);
            }
        }
Beispiel #7
0
        public override async Task <ConnectResult> ProtectedConnect(ConnectArgument arg)
        {
            var dest       = arg.Dest;
            var baseResult = await ConnectHelper.Connect(this, server, connect_timeout);

            if (!baseResult.Ok)
            {
                return(baseResult);
            }
            try {
                var dataStream = getEncryptionStream(baseResult.Stream);
                var bytes      = dest.ToSocks5Bytes();
                await dataStream.WriteAsync(bytes);

                return(CreateConnectResultWithStream(dataStream));
            } catch (Exception) {
                MyStream.CloseWithTimeout(baseResult.Stream);
                throw;
            }
        }
Beispiel #8
0
            public async void Start()
            {
                try {
                    if (!await socks5svr.ProcessAsync())
                    {
                        return;
                    }
                    this.Dest.Host  = socks5svr.TargetAddr;
                    this.Dest.Port  = socks5svr.TargetPort;
                    this.DataStream = _stream;
                    if (_adapter.fastreply)
                    {
                        await OnConnectionResult(new ConnectResult(null, ConnectResultEnum.OK)).CAF();
                    }

                    await _adapter.HandleIncommingConnection(this, outRef);
                } catch (Exception e) {
                    _adapter.Logger.exception(e, Logging.Level.Warning, "listener");
                } finally {
                    MyStream.CloseWithTimeout(_stream).Forget();
                }
            }