Beispiel #1
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 #2
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 #3
0
        public override async Task HandleTcpConnection(InConnectionTcp connection)
        {
            var stream = await connection.HandleAndGetStream(this);

            HttpConnection httpConnection = CreateHttpConnectionFromMyStream(stream, HttpSvr);
            await httpConnection.Process();
        }
Beispiel #4
0
        public override async Task HandleTcpConnection(InConnectionTcp connection)
        {
RETRY:
            CheckPool();
            bool isConnFromPool = true;
            var  conn           = TryGetConnection();

            if (conn == null)
            {
                isConnFromPool = false;
                conn           = await NewConnection();
            }
            var usedCount = conn.UsedCount;

            Connection.SessionStream s;
            try {
                conn.Open();
                s = conn.CurrentSession;
                await s.WriteHeader(connection.Dest);
            } catch (Exception e) {
                Logger.error($"{(usedCount > 0 ? $"reusing({usedCount}) " : "")}" +
                             $"connection error{(isConnFromPool ? " (will retry)" : "")}:" +
                             $" {e.Message} on {conn.ws.BaseStream}");
                conn.Close();
                if (isConnFromPool)
                {
                    goto RETRY;
                }
                throw;
            }
            await connection.HandleAndPutStream(this, s.AsMyStream);

            TryPut(conn).Forget();
        }
Beispiel #5
0
        private Task handleConnectProxy(HttpConnection p)
        {
            if (@out == null)
            {
                Logger.info($"unhandled tunnel request (no 'out'): {p.Method} {p.Url}");
                return(AsyncHelper.CompletedTask);
            }
            p.EnableKeepAlive = false;
            var    dest     = AddrPort.Parse(p.Url);
            var    stream   = p.SwitchProtocol();
            var    mystream = getStream(p);
            string str      = "(tunnel) " + p.epPair.ToString();
            var    inc      = InConnectionTcp.Create(this, dest, async(r) => {
                if (r.Ok)
                {
                    await mystream.WriteAsync(ConnectedResponse);
                    return(mystream);
                }
                else
                {
                    mystream.Close().Forget();
                    return(null);
                }
            }, () => str);

            return(HandleIncommingConnection(inc));
        }
Beispiel #6
0
        public async Task HandleTcpConnection(InConnectionTcp connection)
        {
            var stream = await connection.HandleAndGetStream(this);

            var httpConn = WebBaseAdapter.CreateHttpConnectionFromMyStream(stream, httpServer);
            await httpConn.Process();
        }
Beispiel #7
0
        public override void OnNewConnection(TcpClient tcpClient)
        {
            Socket socket     = tcpClient.Client;
            var    epPair     = EPPair.FromSocket(socket);
            var    dataStream = GetMyStreamFromSocket(socket);
            var    dest       = this.dest.WithDefaultPort(listen.Port);

            HandleIncommingConnection(InConnectionTcp.Create(this, dest, dataStream, epPair.ToString()));
        }
Beispiel #8
0
        public override async void OnNewConnection(TcpClient client)
        {
            try {
                using (client) {
                    var socket     = client.Client;
                    var remoteEP   = socket.RemoteEndPoint as IPEndPoint;
                    var dataStream = getEncryptionStream(GetMyStreamFromSocket(socket));
                    var buf        = new BytesSegment(new byte[3]);
                    await dataStream.ReadFullAsyncR(buf).CAF(); // read ahead

                    var    addrType   = (Socks5Server.AddrType)buf[0];
                    string addrString = null;
                    switch (addrType)
                    {
                    case Socks5Server.AddrType.IPv4Address:
                    case Socks5Server.AddrType.IPv6Address:
                        var buf2 = new byte[addrType == Socks5Server.AddrType.IPv4Address ? 4 : 16];
                        buf2[0] = buf[1];
                        buf2[1] = buf[2];
                        await dataStream.ReadFullAsyncR(new BytesSegment(buf2, 2, buf2.Length - 2)).CAF();

                        var ip = new IPAddress(buf2);
                        addrString = ip.ToString();
                        break;

                    case Socks5Server.AddrType.DomainName:
                        var length = buf[1];
                        if (length == 0)
                        {
                            Logger.warning($"zero addr length ({remoteEP})");
                            await Task.Delay(10 * 1000).CAF();

                            return;
                        }
                        var dnBuf = new byte[length];
                        dnBuf[0] = buf[2];
                        await dataStream.ReadFullAsyncR(new BytesSegment(dnBuf, 1, length - 1)).CAF();

                        addrString = Encoding.ASCII.GetString(dnBuf, 0, length);
                        break;

                    default:
                        Logger.warning($"unknown addr type {addrType} ({remoteEP})");
                        await Task.Delay(10 * 1000 + NaiveUtils.Random.Next(20 * 1000)).CAF();

                        return;
                    }
                    await dataStream.ReadFullAsyncR(buf.Sub(0, 2)).CAF();

                    int port = buf[0] << 8 | buf[1];
                    var dest = new AddrPort(addrString, port);
                    await Controller.HandleInConnection(InConnectionTcp.Create(this, dest, dataStream, $"remote={remoteEP}")).CAF();
                }
            } catch (Exception e) {
                Logger.exception(e, Logging.Level.Error, "handling connection");
            }
        }
Beispiel #9
0
        public override void OnNewConnection(TcpClient tcpClient)
        {
            Socket socket     = tcpClient.Client;
            var    epPair     = EPPair.FromSocket(socket);
            var    dataStream = GetMyStreamFromSocket(socket);
            var    dest       = Unsafe.GetOriginalDst(socket, Logger);

            HandleIncommingConnection(InConnectionTcp.Create(this, dest, dataStream, epPair.ToString()));
        }
Beispiel #10
0
        private async void Handle(TcpClient client)
        {
            try {
                var socketStream = GetMyStreamFromSocket(client.Client);
                var ws           = new WebSocket(socketStream, false, true);
                if (timeout > 0)
                {
                    ws.AddToManaged(timeout / 2, timeout);
                }
                using (ws) {
                    var stream = new Naive0.Connection(ws, enc)
                    {
                        PerSessionIV = per_session_iv
                    };
                    while (true)
                    {
                        var      s = stream.Open();
                        AddrPort dest;
                        try {
                            dest = await s.ReadHeader();
                        } catch (Exception) {
                            return;
                        }
                        if (logging)
                        {
                            Logger.info($"{socketStream} dest={dest} used={stream.UsedCount}");
                        }
                        var conn = InConnectionTcp.Create(this, dest, s.AsMyStream);
                        await this.HandleIncommingConnection(conn);

                        if (!await s.TryShutdownForReuse())
                        {
                            break;
                        }
                    }
                }
            } catch (Exception e) {
                Logger.exception(e);
            }
        }
Beispiel #11
0
        public static Task <ConnectResult> ConnectWrapper(IConnectionHandler handler, ConnectArgument arg)
        {
            var tcs    = new TaskCompletionSource <ConnectResult>();
            var newinc = InConnectionTcp.Create(arg.InAdapter, arg.Dest, async(r) => {
                if (r.Ok)
                {
                    var stream = new LoopbackStream();
                    r.Stream   = stream;
                    tcs.SetResult(r);
                    return(stream.Another);
                }
                else
                {
                    tcs.SetResult(r);
                    return(null);
                }
            });

            newinc.Url = arg.Url;
            newinc.DestOriginalName = arg.DestOriginalName;
            NaiveUtils.RunAsyncTask(async() => {
                try {
                    await handler.HandleTcpConnection(newinc).CAF();
                } catch (Exception e) {
                    tcs.SetException(e);
                    return;
                }
                if (newinc.IsRedirected && tcs.Task.IsCompleted == false)
                {
                    tcs.SetResult(ConnectResult.RedirectTo(handler, newinc.Redirected));
                }
                else
                {
                    tcs.SetException(new Exception("handleConnection() did nothing."));
                }
            });
            return(tcs.Task);
        }
Beispiel #12
0
        public async Task ClientList(HttpConnection p, InConnectionTcp con)
        {
            p.setStatusCode("200 OK");
            var sb = new StringBuilder(512);

            sb.AppendLine("<html><head><meta name='viewport' content='width=device-width, initial-scale=1'></head>")
            .AppendLine($"<body style='margin: 0 auto; max-width: 100ch; padding: 8px;'>" +
                        $"<h1 style='text-align: center'>NNetwork '{domain}'</h1>");
            sb.AppendLine("<h2>Connected Clients</h2><pre style='overflow: auto;'>");
            var curTime = WebSocket.CurrentTime;

            foreach (var item in clients)
            {
                sb.Append(item.Ip.ToString());
                foreach (var name in item.tags)
                {
                    sb.Append('\t').Append(name);
                }
                sb.Append("\tCreateTime: ").Append(item.CreateTime - curTime).AppendLine();
            }
            sb.AppendLine()
            .AppendLine("</pre><h2>Request Info</h2><pre style='overflow: auto;'>")
            .AppendLine($"Url: {p.Url}")
            .AppendLine($"Host: {p.Host}")
            .AppendLine($"BaseStream: {p.myStream}")
            .AppendLine($"EndPoint: {p.epPair}")
            .AppendLine($"Server Time: {DateTime.Now}");
            if (con != null)
            {
                sb.AppendLine($"Dest: {con.Dest}");
            }
            sb.AppendLine()
            .AppendLine("RawRequest:")
            .Append(HttpUtil.HtmlEncode(p.RawRequest))
            .AppendLine("</pre></body></html>");
            await p.EndResponseAsync(sb.ToString());
        }
Beispiel #13
0
 public override Task HandleTcpConnection(InConnectionTcp connection)
 => HandleConnection(connection as InConnection);
Beispiel #14
0
 public override Task HandleTcpConnection(InConnectionTcp connection)
 {
     return(HandleConnection(connection as InConnection));
 }
Beispiel #15
0
 public override async Task HandleTcpConnection(InConnectionTcp connection)
 {
     await connection.HandleAndGetStream(GetConnectResult());
 }
Beispiel #16
0
 public abstract Task HandleTcpConnection(InConnectionTcp connection);
Beispiel #17
0
        public override async Task HandleTcpConnection(InConnectionTcp connection)
        {
            var host = connection.Dest.Host;
            var name = TryGetName(host);

            if (name != null)
            {
                if (name.Length == 0 || name == list_name)
                {
                    if (connection.Dest.Port == 80)
                    {
                        goto LIST;
                    }
                }
                else
                {
                    var cli = FindClientByName(name);
                    if (cli != null)
                    {
                        await cli.HandleConnection(connection);
                    }
                    else if (if_notfound == null)
                    {
                        await connection.HandleAndGetStream(new ConnectResult(this, ConnectResultEnum.Failed) {
                            FailedReason = "no such client"
                        });
                    }
                    else
                    {
                        connection.RedirectTo(if_notfound);
                    }
                }
            }
            else
            {
                if (enable_ip && AddrPort.TryParseIpv4(host, out var ip))
                {
                    if (ipmap.TryGetValue(ip, out var cli))
                    {
                        await cli.HandleConnection(connection);

                        return;
                    }
                    else if (ip == listIp)
                    {
                        goto LIST;
                    }
                }
                if (if_notmatch != null)
                {
                    connection.RedirectTo(if_notmatch);
                }
            }
            return;

LIST:
            var stream = await connection.HandleAndGetStream(this);

            var httpConnection = CreateHttpConnectionFromMyStream(stream, HttpSvr);

            httpConnection.SetTag("connection", connection);
            await httpConnection.Process();
        }