Example #1
0
        private async Task ProcessConsumeRequestAsync(int consumerPort, string clientApp, TcpClient consumerClient, CancellationToken ct)
        {
            TcpTunnel tunnel = new TcpTunnel {
                ConsumerClient = consumerClient
            };

            ServerContext.PortAppMap[consumerPort].Tunnels.Add(tunnel);
            //Logger.Debug("consumer已连接:" + consumerClient.Client.RemoteEndPoint.ToString());
            ServerContext.ConnectCount += 1;
            //II.弹出先前已经准备好的socket
            TcpClient s2pClient = await ConnectionManager.GetClient(consumerPort);

            if (s2pClient == null)
            {
                Logger.Debug($"端口{consumerPort}获取反弹连接超时,关闭传输。");
                //获取clientid
                //关闭本次连接
                ServerContext.CloseAllSourceByClient(ServerContext.PortAppMap[consumerPort].ClientId);
            }

            tunnel.ClientServerClient = s2pClient;
            //✳关键过程✳
            //III.发送一个字节过去促使客户端建立转发隧道,至此隧道已打通
            //客户端接收到此消息后,会另外分配一个备用连接
            s2pClient.GetStream().WriteAndFlushAsync(new byte[] { 0x01 }, 0, 1);

            await TcpTransferAsync(consumerClient, s2pClient, clientApp, ct);
        }
Example #2
0
        private async Task ProcessConsumeRequestAsync(int consumerPort, string clientApp, TcpClient consumerClient, CancellationToken ct)
        {
            TcpTunnel tunnel = new TcpTunnel();

            tunnel.ConsumerClient = consumerClient;
            ServerContext.PortAppMap[consumerPort].Tunnels.Add(tunnel);
            Logger.Debug("consumer已连接:" + consumerClient.Client.RemoteEndPoint.ToString());

            //II.弹出先前已经准备好的socket
            TcpClient s2pClient = await ConnectionManager.GetClient(consumerPort);

            tunnel.ClientServerClient = s2pClient;
            //✳关键过程✳
            //III.发送一个字节过去促使客户端建立转发隧道,至此隧道已打通
            //客户端接收到此消息后,会另外分配一个备用连接
            s2pClient.GetStream().WriteAndFlushAsync(new byte[] { 0x01 }, 0, 1);

            await TcpTransferAsync(consumerClient, s2pClient, clientApp, ct);
        }
Example #3
0
        /// <summary>
        /// 同时侦听来自consumer的链接和到provider的链接
        /// </summary>
        /// <param name="consumerlistener"></param>
        /// <param name="ct"></param>
        /// <returns></returns>
        async Task ListenConsumeAsync(int consumerPort, CancellationToken ct)
        {
            try
            {
                var consumerlistener = new TcpListener(IPAddress.Any, consumerPort);
                consumerlistener.Start(1000);
                //给两个listen,同时监听3端
                var clientCounter = 0;
                while (!ct.IsCancellationRequested)
                {
                    //目标的代理服务联通了,才去处理consumer端的请求。
                    Logger.Debug("listening serviceClient....Port:" + consumerPort);
                    TcpClient consumerClient = await consumerlistener.AcceptTcpClientAsync();

                    //记录tcp隧道,消费端
                    TcpTunnel tunnel = new TcpTunnel();
                    tunnel.ConsumerClient = consumerClient;
                    ClientConnectionManager.GetInstance().PortAppMap[consumerPort].Tunnels.Add(tunnel);
                    Logger.Debug("consumer已连接:" + consumerClient.Client.RemoteEndPoint.ToString());
                    //消费端连接成功,连接


                    //需要端口
                    TcpClient s2pClient = await ConnectionManager.GetClient(consumerPort);

                    //记录tcp隧道,客户端
                    tunnel.ClientServerClient = s2pClient;
                    //✳关键过程✳
                    //连接完之后发送一个字节过去促使客户端建立转发隧道
                    await s2pClient.GetStream().WriteAsync(new byte[] { 1 }, 0, 1);

                    clientCounter++;

                    TcpTransferAsync(consumerlistener, consumerClient, s2pClient, clientCounter, ct);
                }
            }
            catch (Exception e)
            {
                Logger.Debug(e);
            }
        }
Example #4
0
        private async Task ProcessConsumeRequestAsync(int consumerPort, string clientApp, TcpClient consumerClient, CancellationToken ct)
        {
            TcpTunnel tunnel = new TcpTunnel {
                ConsumerClient = consumerClient
            };
            var       nspApp         = ServerContext.PortAppMap[consumerPort];
            TcpClient s2pClient      = null;
            Stream    consumerStream = consumerClient.GetStream(); //; = consumerClient.GetStream().ProcessSSL(TestCert);
            Stream    providerStream = null;                       // = s2pClient.GetStream();

            byte[] restBytes = null;
            //int restBytesLength = 0;
            try
            {
                if (nspApp.ProtocolInGroup == Protocol.HTTP || nspApp.ProtocolInGroup == Protocol.HTTPS)
                {//不论是http协议还是https协议,有证书就加密
                    if (ServerContext.PortCertMap.TryGetValue(consumerPort.ToString(), out X509Certificate cert2))
                    {
                        consumerStream = consumerStream.ProcessSSL(cert2);
                    }
                    var tp = await ReadHostName(consumerStream);

                    if (tp == null)
                    {
                        Server.Logger.Debug("未在请求中找到主机名"); return;
                    }

                    string host = tp.Item1;
                    restBytes = Encoding.UTF8.GetBytes(tp.Item2); //预发送bytes,因为这部分用来抓host消费掉了
                    //restBytesLength = tp.Item3;
                    s2pClient = await ConnectionManager.GetClient(consumerPort, host);

                    nspApp[host].Tunnels.Add(tunnel);//bug修改:建立隧道
                }
                else
                {
                    s2pClient = await ConnectionManager.GetClient(consumerPort);

                    nspApp.ActivateApp.Tunnels.Add(tunnel);//bug修改:建立隧道
                }
            }
            catch (TimeoutException ex)
            {
                Logger.Debug($"端口{consumerPort}获取反弹连接超时,关闭传输。=>" + ex.Message);
                //获取clientid
                //关闭本次连接
                ServerContext.CloseAllSourceByClient(ServerContext.PortAppMap[consumerPort].ActivateApp.ClientId);
                return;
            }
            catch (KeyNotFoundException ex)
            {
                Server.Logger.Debug("未绑定此host:=>" + ex.Message);
                consumerClient.Close();
                return;
            }

            //Logger.Debug("consumer已连接:" + consumerClient.Client.RemoteEndPoint.ToString());
            ServerContext.ConnectCount += 1;

            //TODO 如果NSPApp中是http,则需要进一步分离,通过GetHTTPClient来分出对应的client以建立隧道
            //if()
            //II.弹出先前已经准备好的socket
            tunnel.ClientServerClient = s2pClient;
            CancellationTokenSource transfering = new CancellationTokenSource();

            //✳关键过程✳
            //III.发送一个字节过去促使客户端建立转发隧道,至此隧道已打通
            //客户端接收到此消息后,会另外分配一个备用连接

            providerStream = s2pClient.GetStream();
            await providerStream.WriteAndFlushAsync(new byte[] { 0x01 }, 0, 1);

            //预发送bytes,因为这部分用来抓host消费掉了,所以直接转发
            if (restBytes != null)
            {
                await providerStream.WriteAsync(restBytes, 0, restBytes.Length, transfering.Token);
            }

            try
            {
                await TcpTransferAsync(consumerStream, providerStream, clientApp, transfering.Token);
            }
            finally
            {
                consumerClient.Close();
                s2pClient.Close();
                transfering.Cancel();
            }
        }
Example #5
0
        private async Task ProcessConsumeTcpRequestAsync(int consumerPort, TcpClient consumerClient, CancellationToken ct)
        {
            TcpTunnel tunnel = new TcpTunnel {
                ConsumerClient = consumerClient
            };
            var       nspAppGroup    = ServerContext.PortAppMap[consumerPort];
            NSPApp    nspApp         = null;
            TcpClient s2pClient      = null;
            Stream    consumerStream = consumerClient.GetStream();
            Stream    providerStream = null;

            byte[] restBytes = null;

            try
            {
                if (nspAppGroup.ProtocolInGroup == Protocol.HTTP /*|| nspAppGroup.ProtocolInGroup == Protocol.HTTPS*/)
                {//不论是http协议还是https协议,有证书就加密
                    if (ServerContext.PortCertMap.TryGetValue(consumerPort.ToString(), out X509Certificate cert2))
                    {
                        consumerStream = consumerStream.ProcessSSL(cert2);
                    }
                    var tp = await ReadHostName(consumerStream);

                    if (tp == null)
                    {
                        Server.Logger.Debug("未在请求中找到主机名"); return;
                    }

                    string host = tp.Item1;
                    restBytes = Encoding.UTF8.GetBytes(tp.Item2); //预发送bytes,因为这部分用来抓host消费掉了
                    //restBytesLength = tp.Item3;
                    s2pClient = await ConnectionManager.GetClientForTcp(consumerPort, host);

                    if (nspAppGroup.ContainsKey(host))
                    {
                        nspAppGroup[host].Tunnels.Add(tunnel); //bug修改:建立隧道
                    }
                    else
                    {
                        Server.Logger.Debug($"不存在host为“{host}”的主机名,但访问端依然以此主机名访问。");
                    }

                    nspApp = nspAppGroup[host];
                }
                else if (nspAppGroup.ProtocolInGroup == Protocol.TCP) //TCP
                {
                    s2pClient = await ConnectionManager.GetClientForTcp(consumerPort);

                    nspAppGroup.ActivateApp.Tunnels.Add(tunnel);//bug修改:建立隧道
                    nspApp = nspAppGroup.ActivateApp;
                }
            }
            catch (TimeoutException ex)
            {
                Logger.Debug($"端口{consumerPort}获取反弹连接超时,关闭传输。=>" + ex.Message);
                //获取clientid
                //关闭本次连接
                ServerContext.CloseAllSourceByClient(ServerContext.PortAppMap[consumerPort].ActivateApp.ClientId);
                return;
            }
            catch (KeyNotFoundException ex)
            {
                Server.Logger.Debug("未绑定此host:=>" + ex.Message);
                consumerClient.Close();
                return;
            }

            ServerContext.ConnectCount += 1;

            //TODO 如果NSPApp中是http,则需要进一步分离,通过GetHTTPClient来分出对应的client以建立隧道
            //II.弹出先前已经准备好的socket
            tunnel.ClientServerClient = s2pClient;
            CancellationTokenSource transfering = new CancellationTokenSource();

            //✳关键过程✳
            //III.发送一个字节过去促使客户端建立转发隧道,至此隧道已打通
            //客户端接收到此消息后,会另外分配一个备用连接

            //TODO 4 增加一个udp转发的选项
            providerStream = s2pClient.GetStream();
            //TODO 5 这里会出错导致无法和客户端通信
            try
            {
                await providerStream.WriteAndFlushAsync(new byte[] { (byte)ControlMethod.TCPTransfer }, 0, 1);//双端标记S0001
            }
            catch
            {
                Logger.Debug($"client:{nspApp.ClientId} app:{nspApp.AppId}写入失败,尝试切断该客户端");
                ServerContext.CloseAllSourceByClient(nspApp.ClientId);
                return;
            }

            //预发送bytes,因为这部分用来抓host消费掉了,所以直接转发
            if (restBytes != null)
            {
                await providerStream.WriteAsync(restBytes, 0, restBytes.Length, transfering.Token);
            }

            //TODO 4 TCP则打通隧道进行转发,UDP直接转发
            // if tcp
            try
            {
                await OpenTcpTransmission(consumerStream, providerStream, nspApp, transfering.Token);
            }
            finally
            {
                consumerClient.Close();
                s2pClient.Close();
                transfering.Cancel();
            }
        }
Example #6
0
        private async Task ProcessConsumeRequestAsync(int consumerPort, string clientApp, TcpClient consumerClient, CancellationToken ct)
        {
            TcpTunnel tunnel = new TcpTunnel {
                ConsumerClient = consumerClient
            };
            var       nspApp    = ServerContext.PortAppMap[consumerPort];
            TcpClient s2pClient = null;

            byte[] restBytes       = null;
            int    restBytesLength = 0;

            //byte[] ToStaticBytes;
            try
            {
                if (nspApp.ProtocolInGroup == Protocol.HTTP)
                {
                    var tp = await ReadHostName(consumerClient);

                    string host = tp.Item1;
                    restBytes       = tp.Item2; //预发送bytes,因为这部分用来抓host消费掉了
                    restBytesLength = tp.Item3;
                    s2pClient       = await ConnectionManager.GetClient(consumerPort, host);

                    //if (s2pClient == null) //TODO 2 关注!不要同时使用一种返回结果 如client为null
                    //{

                    //}
                }
                else
                {
                    s2pClient = await ConnectionManager.GetClient(consumerPort);
                }
            }
            catch (TimeoutException ex)
            {
                Logger.Debug($"端口{consumerPort}获取反弹连接超时,关闭传输。=>" + ex.Message);
                //获取clientid
                //关闭本次连接
                ServerContext.CloseAllSourceByClient(ServerContext.PortAppMap[consumerPort].ActivateApp.ClientId);
                return;
            }
            catch (KeyNotFoundException ex)
            {
                Server.Logger.Debug("未绑定此host:=>" + ex.Message);
                consumerClient.Close();
                return;
            }

            //Logger.Debug("consumer已连接:" + consumerClient.Client.RemoteEndPoint.ToString());
            ServerContext.ConnectCount += 1;

            //TODO 如果NSPApp中是http,则需要进一步分离,通过GetHTTPClient来分出对应的client以建立隧道
            //if()
            //II.弹出先前已经准备好的socket
            tunnel.ClientServerClient = s2pClient;
            //✳关键过程✳
            //III.发送一个字节过去促使客户端建立转发隧道,至此隧道已打通
            //客户端接收到此消息后,会另外分配一个备用连接
            await s2pClient.GetStream().WriteAndFlushAsync(new byte[] { 0x01 }, 0, 1);

            //预发送bytes,因为这部分用来抓host消费掉了,所以直接转发
            if (restBytes != null)
            {
                _ = s2pClient.GetStream().WriteAsync(restBytes, 0, restBytesLength, ct);
            }

            await TcpTransferAsync(consumerClient, s2pClient, clientApp, ct);
        }