예제 #1
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));
        }
예제 #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();
            }
        }
예제 #3
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");
            }
        }
예제 #4
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()));
        }
예제 #5
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()));
        }
예제 #6
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);
            }
        }
예제 #7
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);
        }