Beispiel #1
0
        public override bool Excute()
        {
            string clientName = BinaryUtils.ReadString(m_data);
            string authCode   = BinaryUtils.ReadString(m_data);

            if (ConfigCenter.Instance.ClientAuthList.Count == 0 || ConfigCenter.Instance.ClientAuthList.Any(t => t.Match(clientName, authCode)))
            {
                bool       isSuccess = true;
                P2PTcpItem item      = new P2PTcpItem();
                item.TcpClient = m_tcpClient;
                if (ClientCenter.Instance.TcpMap.ContainsKey(clientName))
                {
                    if (ClientCenter.Instance.TcpMap[clientName].TcpClient.IsDisConnected)
                    {
                        ClientCenter.Instance.TcpMap[clientName].TcpClient.SafeClose();
                        ClientCenter.Instance.TcpMap[clientName] = item;
                    }
                    else
                    {
                        isSuccess = false;
                        Send_0x0101 sendPacket = new Send_0x0101(m_tcpClient, false, $"ClientName:{clientName} 已被使用");
                        m_tcpClient.Client.Send(sendPacket.PackData());
                        m_tcpClient.SafeClose();

                        try
                        {
                            ClientCenter.Instance.TcpMap[clientName].TcpClient.Client.Send(new Send_0x0052().PackData());
                        }
                        catch (Exception)
                        {
                            ClientCenter.Instance.TcpMap.Remove(clientName);
                        }
                    }
                }
                else
                {
                    ClientCenter.Instance.TcpMap.Add(clientName, item);
                }
                if (isSuccess)
                {
                    m_tcpClient.ClientName = clientName;
                    Send_0x0101 sendPacket = new Send_0x0101(m_tcpClient, true, $"客户端{clientName}认证通过");
                    m_tcpClient.Client.Send(sendPacket.PackData());
                }
            }
            else
            {
                Send_0x0101 sendPacket = new Send_0x0101(m_tcpClient, false, $"客户端{clientName}认证失败");
                m_tcpClient.Client.Send(sendPacket.PackData());
                m_tcpClient.SafeClose();
            }

            return(true);
        }
Beispiel #2
0
        /// <summary>
        ///     监听映射端口并转发数据(ip直接转发模式)
        /// </summary>
        /// <param name="readClient"></param>
        private void ListenPortMapTcpWithIp(P2PTcpClient readClient)
        {
            if (readClient.ToClient == null || !readClient.ToClient.Connected)
            {
                LogUtils.Warning($"【失败】IP数据转发:绑定的Tcp连接已断开.");
                readClient.SafeClose();
                return;
            }
            byte[] buffer = new byte[P2PGlobal.P2PSocketBufferSize];
            readClient.ReceiveBufferSize = P2PGlobal.P2PSocketBufferSize;
            NetworkStream readStream = readClient.GetStream();
            NetworkStream toStream   = readClient.ToClient.GetStream();

            try
            {
                while (readClient.Connected)
                {
                    int curReadLength = readStream.ReadSafe(buffer, 0, buffer.Length);
                    if (curReadLength > 0)
                    {
                        if (readClient.ToClient != null)
                        {
                            toStream.Write(buffer, 0, curReadLength);
                        }
                        else
                        {
                            LogUtils.Warning($"【失败】IP数据转发:目标Tcp连接已释放.");
                            readClient.SafeClose();
                            break;
                        }
                    }
                    else
                    {
                        LogUtils.Warning($"【失败】IP数据转发:Tcp连接已断开.");
                        //如果tcp已关闭,需要关闭相关tcp
                        try
                        {
                            readClient.ToClient?.SafeClose();
                        }
                        finally { }
                        break;
                    }
                }
            }
            finally
            {
                LogUtils.Warning($"【失败】IP数据转发:目标Tcp连接已断开.");
                readClient.SafeClose();
            }
        }
        /// <summary>
        ///     匹配对应的Command命令
        /// </summary>
        /// <param name="tcpClient"></param>
        /// <param name="packet"></param>
        /// <returns></returns>
        public static P2PCommand FindCommand(P2PTcpClient tcpClient, ReceivePacket packet)
        {
            P2PCommand command   = null;
            AppCenter  appCenter = EasyInject.Get <AppCenter>();

            if (appCenter.AllowAnonymous.Contains(packet.CommandType) || tcpClient.IsAuth)
            {
                if (appCenter.CommandDict.ContainsKey(packet.CommandType))
                {
                    Type type = appCenter.CommandDict[packet.CommandType];
                    command = Activator.CreateInstance(type, tcpClient, packet.Data.Select(t => t).ToArray()) as P2PCommand;
                }
                else
                {
                    LogUtils.Warning($"{tcpClient.RemoteEndPoint}请求了未知命令{packet.CommandType}");
                }
            }
            else
            {
                tcpClient?.SafeClose();
                tcpClient.ToClient?.SafeClose();
                LogUtils.Warning($"拦截{tcpClient.RemoteEndPoint}未授权命令");
            }
            return(command);
        }
        public override bool Excute()
        {
            try
            {
                string token          = BinaryUtils.ReadString(data);
                int    mapPort        = BinaryUtils.ReadInt(data);
                string remoteEndPoint = BinaryUtils.ReadString(data);;
                if (ConfigCenter.Instance.AllowPortList.Any(t => t.Match(mapPort, m_tcpClient.ClientName)))
                {
                    P2PTcpClient portClient   = new P2PTcpClient("127.0.0.1", mapPort);
                    P2PTcpClient serverClient = new P2PTcpClient(ConfigCenter.Instance.ServerAddress, ConfigCenter.Instance.ServerPort);
                    portClient.IsAuth     = serverClient.IsAuth = true;
                    portClient.ToClient   = serverClient;
                    serverClient.ToClient = portClient;


                    Models.Send.Send_0x0211 sendPacket = new Models.Send.Send_0x0211(token);
                    LogUtils.Info($"命令:0x0211 正在绑定内网穿透(2端)通道 {portClient.RemoteEndPoint}->服务器->{remoteEndPoint}{Environment.NewLine}token:{token} ");
                    int length = serverClient.Client.Send(sendPacket.PackData());
                    AppCenter.Instance.StartNewTask(() => { Global_Func.ListenTcp <Models.Receive.Packet_0x0212>(portClient); });
                    AppCenter.Instance.StartNewTask(() => { Global_Func.ListenTcp <Models.Receive.Packet_ToPort>(serverClient); });
                }
                else
                {
                    LogUtils.Warning($"命令:0x0211 无权限,端口:{mapPort}");
                    m_tcpClient.SafeClose();
                }
            }
            catch (Exception ex)
            {
                LogUtils.Warning($"命令:0x0211 错误:{Environment.NewLine} {ex}");
            }
            return(true);
        }
        /// <summary>
        ///     匹配对应的Command命令
        /// </summary>
        /// <param name="tcpClient"></param>
        /// <param name="packet"></param>
        /// <returns></returns>
        public static P2PCommand FindCommand(P2PTcpClient tcpClient, ReceivePacket packet)
        {
            P2PCommand command = null;

            if (AppCenter.Instance.AllowAnonymous.Contains(packet.CommandType) || tcpClient.IsAuth)
            {
                if (AppCenter.Instance.CommandDict.ContainsKey(packet.CommandType))
                {
                    Type type = AppCenter.Instance.CommandDict[packet.CommandType];
                    command = Activator.CreateInstance(type, tcpClient, packet.Data) as P2PCommand;
                }
                else
                {
                    LogUtils.Warning($"{tcpClient.RemoteEndPoint}请求了未知命令{packet.CommandType}");
                }
            }
            else
            {
                tcpClient.SafeClose();
                if (tcpClient.ToClient != null && tcpClient.ToClient.Connected)
                {
                    tcpClient.ToClient.SafeClose();
                }
                LogUtils.Warning($"拦截{tcpClient.RemoteEndPoint}未授权命令");
            }
            return(command);
        }
Beispiel #6
0
        public override bool Excute()
        {
            LogUtils.Trace($"开始处理消息:0x0201");
            int step = BinaryUtils.ReadInt(m_data);

            //是否第一步创建
            if (step == 1)
            {
                //token,servername,port
                string token      = BinaryUtils.ReadString(m_data);
                string clientName = BinaryUtils.ReadString(m_data);
                int    clientPort = BinaryUtils.ReadInt(m_data);
                int    p2pType    = BinaryUtils.ReadInt(m_data);
                if (p2pTypeDict.ContainsKey(token))
                {
                    p2pTypeDict[token] = p2pType;
                }
                else
                {
                    p2pTypeDict.Add(token, p2pType);
                }
                P2PStart_ServerTransfer(token, clientName, clientPort, p2pType);
            }
            else if (step == 3)
            {
                string clientName = BinaryUtils.ReadString(m_data);
                m_tcpClient.ClientName = clientName;
                string token = BinaryUtils.ReadString(m_data);
                if (clientCenter.WaiteConnetctTcp.ContainsKey(token))
                {
                    if (p2pTypeDict.ContainsKey(token) && p2pTypeDict[token] >= 1)
                    {
                        P2PBind_DirectConnect(token);
                    }
                    else
                    {
                        P2PBind_ServerTransfer(token);
                    }
                    p2pTypeDict.Remove(token);
                }
                else
                {
                    clientCenter.WaiteConnetctTcp.Add(token, m_tcpClient);
                    LogUtils.Debug($"正在等待隧道连接绑定 token:{token}.");
                    EasyInject.Get <AppCenter>().StartNewTask(() =>
                    {
                        Thread.Sleep(appCenter.Config.P2PWaitConnectTime);
                        if (clientCenter.WaiteConnetctTcp.ContainsKey(token))
                        {
                            LogUtils.Debug($"等待隧道连接绑定已超时  token:{token}.");
                            EasyOp.Do(() => m_tcpClient.SafeClose());
                            clientCenter.WaiteConnetctTcp.Remove(token);
                            p2pTypeDict.Remove(token);
                        }
                    });
                }
            }
            return(true);
        }
 /// <summary>
 ///     监听映射端口并转发数据(ip直接转发模式)
 /// </summary>
 /// <param name="readClient"></param>
 private void ListenPortMapTcpWithIp(P2PTcpClient readClient)
 {
     if (readClient.ToClient == null || !readClient.ToClient.Connected)
     {
         LogUtils.Warning($"数据转发(ip模式)失败:绑定的Tcp连接已断开.");
         readClient.SafeClose();
         return;
     }
     TcpCenter.Instance.ConnectedTcpList.Add(readClient);
     byte[] buffer = new byte[P2PGlobal.P2PSocketBufferSize];
     try
     {
         NetworkStream readStream = readClient.GetStream();
         NetworkStream toStream   = readClient.ToClient.GetStream();
         while (readClient.Connected)
         {
             int curReadLength = readStream.ReadSafe(buffer, 0, buffer.Length);
             if (curReadLength > 0)
             {
                 toStream.Write(buffer, 0, curReadLength);
             }
             else
             {
                 LogUtils.Warning($"端口映射转发(ip模式):源Tcp连接已断开.");
                 //如果tcp已关闭,需要关闭相关tcp
                 try
                 {
                     readClient.ToClient.SafeClose();
                 }
                 finally
                 {
                 }
                 break;
             }
         }
     }
     catch (Exception ex)
     {
         LogUtils.Warning($"端口映射转发(ip模式):目标Tcp连接已断开.");
         readClient.SafeClose();
     }
     TcpCenter.Instance.ConnectedTcpList.Remove(readClient);
 }
Beispiel #8
0
        public override bool Excute()
        {
            bool ret = true;

            LogUtils.Trace($"开始处理消息:0x0211");
            string token     = BinaryUtils.ReadString(m_data);
            bool   isSuccess = true;
            string msg       = "";

            if (m_data.PeekChar() >= 0)
            {
                isSuccess = BinaryUtils.ReadBool(m_data);
                msg       = BinaryUtils.ReadString(m_data);
            }
            if (isSuccess)
            {
                if (clientCenter.WaiteConnetctTcp.ContainsKey(token))
                {
                    P2PTcpClient client = clientCenter.WaiteConnetctTcp[token];
                    clientCenter.WaiteConnetctTcp.Remove(token);
                    client.IsAuth        = m_tcpClient.IsAuth = true;
                    client.ToClient      = m_tcpClient;
                    m_tcpClient.ToClient = client;
                    LogUtils.Debug($"命令:0x0211 已绑定内网穿透(2端)通道 {client.RemoteEndPoint}->{m_tcpClient.RemoteEndPoint}");
                    //监听client
                    EasyOp.Do(() => Global_Func.ListenTcp <Packet_0x0212>(client), ex =>
                    {
                        LogUtils.Debug($"命令:0x0211 绑定内网穿透(2端)通道失败,目标Tcp连接已断开");
                        ret = false;
                    });
                }
                else
                {
                    LogUtils.Debug($"命令:0x0211 绑定内网穿透(2端)通道失败,绑定超时");
                    ret = false;
                }
            }
            else
            {
                //失败消息是客户端与服务端的通讯tcp发送的,不能关闭tcp连接
                LogUtils.Debug($"命令:0x0211 From 客户端:{msg}  token:{token}");
                if (clientCenter.WaiteConnetctTcp.ContainsKey(token))
                {
                    //关闭源tcp
                    P2PTcpClient client = clientCenter.WaiteConnetctTcp[token];
                    EasyOp.Do(() => {
                        client?.SafeClose();
                    });
                    clientCenter.WaiteConnetctTcp.Remove(token);
                }
                ret = true;
            }

            return(ret);
        }
Beispiel #9
0
        public static bool BindTcp(P2PTcpClient readTcp, P2PTcpClient toTcp)
        {
            //TcpCenter.Instance.ConnectedTcpList.Add(readTcp);
            //TcpCenter.Instance.ConnectedTcpList.Add(toTcp);
            bool           ret          = true;
            RelationTcp_Ip toRelation   = new RelationTcp_Ip();
            RelationTcp_Ip fromRelation = new RelationTcp_Ip();

            EasyOp.Do(() =>
            {
                fromRelation.writeTcp = toRelation.readTcp = readTcp;
                fromRelation.writeSs  = toRelation.readSs = readTcp.GetStream();
                fromRelation.readTcp  = toRelation.writeTcp = toTcp;
                fromRelation.readSs   = toRelation.writeSs = toTcp.GetStream();
                toRelation.buffer     = new byte[P2PGlobal.P2PSocketBufferSize];
                fromRelation.buffer   = new byte[P2PGlobal.P2PSocketBufferSize];
                StartTransferTcp_Ip(toRelation);
            },
                      () =>
            {
                EasyOp.Do(() =>
                {
                    StartTransferTcp_Ip(fromRelation);
                },
                          ex =>
                {
                    LogUtils.Debug($"绑定Tcp失败:{Environment.NewLine}{ex}");
                    EasyOp.Do(() => { readTcp.SafeClose(); });
                    ret = false;
                });
            },
                      ex =>
            {
                LogUtils.Debug($"绑定Tcp失败:{Environment.NewLine}{ex}");
                EasyOp.Do(() => { readTcp.SafeClose(); });
                EasyOp.Do(() => { toTcp.SafeClose(); });
                ret = false;
            });
            return(ret);
        }
        /// <summary>
        /// 直接转发类型的端口监听,接收新tcp回调方法
        /// </summary>
        /// <param name="ar"></param>
        public void AcceptSocket_Ip(IAsyncResult ar)
        {
            ListenSt    st       = (ListenSt)ar.AsyncState;
            TcpListener listener = st.listener;
            PortMapItem item     = st.item;
            Socket      socket   = null;

            try
            {
                socket = listener.EndAcceptSocket(ar);
            }
            catch (Exception ex)
            {
                LogUtils.Error(ex.ToString());
                return;
            }
            listener.BeginAcceptSocket(AcceptSocket_Ip, st);
            P2PTcpClient tcpClient = new P2PTcpClient(socket);
            P2PTcpClient ipClient  = null;

            try
            {
                ipClient = new P2PTcpClient(item.RemoteAddress, item.RemotePort);
            }
            catch (Exception ex)
            {
                tcpClient?.SafeClose();
                LogUtils.Debug($"建立隧道失败:{item.LocalPort}->{item.RemoteAddress}:{item.RemotePort}{Environment.NewLine}{ex}");
            }
            if (ipClient.Connected)
            {
                tcpClient.ToClient = ipClient;
                ipClient.ToClient  = tcpClient;
                RelationTcp toRelation = new RelationTcp();
                toRelation.readTcp  = tcpClient;
                toRelation.readSs   = tcpClient.GetStream();
                toRelation.writeTcp = tcpClient.ToClient;
                toRelation.writeSs  = tcpClient.ToClient.GetStream();
                toRelation.buffer   = new byte[P2PGlobal.P2PSocketBufferSize];
                RelationTcp fromRelation = new RelationTcp();
                fromRelation.readTcp  = toRelation.writeTcp;
                fromRelation.readSs   = toRelation.writeSs;
                fromRelation.writeTcp = toRelation.readTcp;
                fromRelation.writeSs  = toRelation.readSs;
                fromRelation.buffer   = new byte[P2PGlobal.P2PSocketBufferSize];
                StartTransferTcp_Ip(toRelation);
                StartTransferTcp_Ip(fromRelation);
            }
        }
        public void TryBindP2PTcp()
        {
            string ip          = BinaryUtils.ReadString(data);
            int    port        = BinaryUtils.ReadInt(data);
            string token       = BinaryUtils.ReadString(data);
            int    maxTryCount = 1;
            bool   isConnected = false;
            int    bindPort    = Convert.ToInt32(m_tcpClient.Client.LocalEndPoint.ToString().Split(':')[1]);

            Task.Factory.StartNew(() =>
            {
                P2PTcpClient p2pClient = new P2PTcpClient();
                p2pClient.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
                p2pClient.Client.Bind(new IPEndPoint(IPAddress.Any, bindPort));
                while (maxTryCount > 0)
                {
                    maxTryCount--;
                    try
                    {
                        p2pClient.Connect(ip, port);
                        p2pClient.UpdateEndPoint();
                        isConnected = true;
                        break;
                    }
                    catch (Exception ex)
                    {
                        LogUtils.Debug($"P2P连接失败:{bindPort}\r\n{ex.ToString()}");
                        Thread.Sleep(100);
                    }
                }
                if (isConnected)
                {
                    LogUtils.Info($"命令:0x0201  内网穿透(P2P模式)连接成功 port:{bindPort} token:{token}");
                    P2PBind_DirectConnect(p2pClient, token);
                }
                else
                {
                    LogUtils.Info($"命令:0x0201  内网穿透(P2P模式)连接失败 port:{bindPort} token:{token}");
                    p2pClient.SafeClose();
                    if (TcpCenter.Instance.WaiteConnetctTcp.ContainsKey(token))
                    {
                        P2PTcpClient portClient = TcpCenter.Instance.WaiteConnetctTcp[token];
                        portClient.SafeClose();
                        TcpCenter.Instance.WaiteConnetctTcp.Remove(token);
                    }
                }
                m_tcpClient.SafeClose();
            });
        }
        public void P2PBind_DirectConnect(string token)
        {
            P2PTcpClient clientA = clientCenter.WaiteConnetctTcp[token];
            P2PTcpClient clientB = m_tcpClient;

            Send_0x0201_Success sendPacketA = new Send_0x0201_Success(14);
            sendPacketA.WriteDirectData(clientB.Client.RemoteEndPoint.ToString(), token);
            Send_0x0201_Success sendPacketB = new Send_0x0201_Success(14);
            sendPacketB.WriteDirectData(clientA.Client.RemoteEndPoint.ToString(), token);

            EasyOp.Do(() => clientA.BeginSend(sendPacketA.PackData()));
            EasyOp.Do(() => clientB.BeginSend(sendPacketB.PackData()));

            EasyOp.Do(() => clientA?.SafeClose());
            EasyOp.Do(() => clientB?.SafeClose());
        }
        /// <summary>
        ///     直接转发类型的端口监听
        /// </summary>
        /// <param name="item"></param>
        private void ListenPortMapPortWithIp(PortMapItem item)
        {
            TcpListener listener = null;

            try
            {
                listener = new TcpListener(string.IsNullOrEmpty(item.LocalAddress) ? IPAddress.Any : IPAddress.Parse(item.LocalAddress), item.LocalPort);
                listener.Start();
            }
            catch (Exception ex)
            {
                LogUtils.Error($"添加端口映射失败:{item.LocalPort}->{item.RemoteAddress}:{item.RemotePort}{Environment.NewLine}{ex.ToString()}");
                return;
            }
            TcpCenter.Instance.ListenerList.Add($"{item.LocalAddress}:{item.LocalPort}", listener);
            LogUtils.Info($"添加端口映射成功:{item.LocalPort}->{item.RemoteAddress}:{item.RemotePort}", false);
            AppCenter.Instance.StartNewTask(() =>
            {
                while (true)
                {
                    Socket socket          = listener.AcceptSocket();
                    P2PTcpClient tcpClient = new P2PTcpClient(socket);
                    AppCenter.Instance.StartNewTask(() =>
                    {
                        P2PTcpClient ipClient = null;
                        try
                        {
                            ipClient = new P2PTcpClient(item.RemoteAddress, item.RemotePort);
                        }
                        catch (Exception ex)
                        {
                            tcpClient.SafeClose();
                            LogUtils.Error($"内网穿透失败:{item.LocalPort}->{item.RemoteAddress}:{item.RemotePort}{Environment.NewLine}{ex}");
                        }
                        if (ipClient.Connected)
                        {
                            tcpClient.ToClient = ipClient;
                            ipClient.ToClient  = tcpClient;
                            AppCenter.Instance.StartNewTask(() => ListenPortMapTcpWithIp(tcpClient));
                            AppCenter.Instance.StartNewTask(() => ListenPortMapTcpWithIp(tcpClient.ToClient));
                        }
                    });
                }
            });
        }
Beispiel #14
0
        public static void ListenTcp <T>(P2PTcpClient tcpClient) where T : ReceivePacket
        {
            RelationTcp_Server relationSt = new RelationTcp_Server();

            relationSt.buffer     = new byte[P2PGlobal.P2PSocketBufferSize];
            relationSt.readTcp    = tcpClient;
            relationSt.msgReceive = Activator.CreateInstance(typeof(T)) as ReceivePacket;
            relationSt.guid       = EasyInject.Get <AppCenter>().CurrentGuid;
            relationSt.readTcp.GetStream().BeginRead(relationSt.buffer, 0, relationSt.buffer.Length, ReadTcp_Server, relationSt);
            //如果20秒仍未授权,则关闭
            TimerUtils.Instance.AddJob(() =>
            {
                if (!tcpClient.IsAuth)
                {
                    EasyOp.Do(() => tcpClient?.SafeClose());
                }
            }, 20000);
        }
Beispiel #15
0
        protected virtual void CreateTcpFromDest_DirectConnect(string token)
        {
            int port = BinaryUtils.ReadInt(data);

            Utils.LogUtils.Debug($"命令:0x0201  正尝试建立P2P模式隧道 token:{token}");
            P2PTcpClient serverClient = new P2PTcpClient();

            serverClient.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);

            EasyOp.Do(() =>
            {
                serverClient.Connect(appCenter.ServerAddress, appCenter.ServerPort);
            },
                      () =>
            {
                serverClient.IsAuth       = true;
                serverClient.P2PLocalPort = port;
                serverClient.UpdateEndPoint();
                Models.Send.Send_0x0201_Bind sendPacket = new Models.Send.Send_0x0201_Bind(token);

                EasyOp.Do(() =>
                {
                    serverClient.BeginSend(sendPacket.PackData());
                },
                          () =>
                {
                    EasyOp.Do(() =>
                    {
                        Global_Func.ListenTcp <ReceivePacket>(serverClient);
                        LogUtils.Debug($"命令:0x0201 P2P模式隧道,已连接到服务器,等待下一步操作 token:{token}");
                    }, ex =>
                    {
                        LogUtils.Debug($"命令:0x0201 P2P模式隧道,服务器连接被强制断开 token:{token}:{Environment.NewLine}{ex}");
                        EasyOp.Do(() => { serverClient.SafeClose(); });
                    });
                }, ex =>
                {
                    LogUtils.Debug($"命令:0x0201 P2P模式隧道,隧道打洞失败 token:{token}:{Environment.NewLine} 隧道被服务器强制断开");
                });
            }, ex =>
            {
                LogUtils.Debug($"命令:0x0201 P2P模式隧道,无法连接服务器 token:{token}:{Environment.NewLine}{ex}");
            });
        }
Beispiel #16
0
        /// <summary>
        ///     直接转发类型的端口监听
        /// </summary>
        /// <param name="item"></param>
        private void ListenPortMapPortWithIp(PortMapItem item)
        {
            TcpListener listener = new TcpListener(IPAddress.Any, item.LocalPort);

            try
            {
                listener.Start();
            }
            catch (Exception ex)
            {
                LogUtils.Error($"【失败】端口映射:{item.LocalPort}->{item.RemoteAddress}:{item.RemotePort}{Environment.NewLine}{ex.ToString()}");
                return;
            }
            ListenerList.Add(listener);
            LogUtils.Info($"【成功】端口映射:{item.LocalPort}->{item.RemoteAddress}:{item.RemotePort}", false);
            AppCenter.Instance.StartNewTask(() =>
            {
                while (true)
                {
                    Socket socket          = listener.AcceptSocket();
                    P2PTcpClient tcpClient = new P2PTcpClient(socket);
                    AppCenter.Instance.StartNewTask(() =>
                    {
                        try
                        {
                            P2PTcpClient ipClient = new P2PTcpClient(item.RemoteAddress, item.RemotePort);
                            tcpClient.ToClient    = ipClient;
                            ipClient.ToClient     = tcpClient;
                        }
                        catch (Exception ex)
                        {
                            tcpClient.SafeClose();
                            LogUtils.Error($"【失败】内网穿透:{item.LocalPort}->{item.RemoteAddress}:{item.RemotePort}{Environment.NewLine}{ex.ToString()}");
                        }
                        if (tcpClient.Connected)
                        {
                            AppCenter.Instance.StartNewTask(() => { ListenPortMapTcpWithIp(tcpClient); });
                            AppCenter.Instance.StartNewTask(() => { ListenPortMapTcpWithIp(tcpClient.ToClient); });
                        }
                    });
                }
            });
        }
        public static void BindTcp(P2PTcpClient readTcp, P2PTcpClient toTcp)
        {
            TcpCenter.Instance.ConnectedTcpList.Add(readTcp);
            byte[]        buffer     = new byte[P2PGlobal.P2PSocketBufferSize];
            NetworkStream readStream = readTcp.GetStream();
            NetworkStream toStream   = toTcp.GetStream();

            while (readTcp.Connected)
            {
                int curReadLength = readStream.ReadSafe(buffer, 0, buffer.Length);
                if (curReadLength > 0)
                {
                    bool isError = true;
                    if (toTcp != null && toTcp.Connected)
                    {
                        try
                        {
                            toStream.Write(buffer, 0, curReadLength);
                            isError = false;
                        }
                        catch { }
                    }
                    if (isError)
                    {
                        LogUtils.Warning($"Tcp连接{toTcp.RemoteEndPoint}已断开.");
                        readTcp.SafeClose();
                        break;
                    }
                }
                else
                {
                    LogUtils.Warning($"Tcp连接{readTcp.RemoteEndPoint}已断开.");
                    //如果tcp已关闭,需要关闭相关tcp
                    toTcp?.SafeClose();
                    break;
                }
            }
            TcpCenter.Instance.ConnectedTcpList.Remove(readTcp);
        }
        public void P2PBind_DirectConnect(string token)
        {
            P2PTcpClient clientA = ClientCenter.Instance.WaiteConnetctTcp[token];
            P2PTcpClient clientB = m_tcpClient;

            Send_0x0201_Success sendPacketA = new Send_0x0201_Success(14);

            sendPacketA.WriteDirectData(clientB.Client.RemoteEndPoint.ToString(), token);
            Send_0x0201_Success sendPacketB = new Send_0x0201_Success(14);

            sendPacketB.WriteDirectData(clientA.Client.RemoteEndPoint.ToString(), token);

            clientA.Client.Send(sendPacketA.PackData());
            clientB.Client.Send(sendPacketB.PackData());

            Task.Factory.StartNew(() =>
            {
                Thread.Sleep(5000);
                clientA.SafeClose();
                clientB.SafeClose();
            });
        }
Beispiel #19
0
        public override bool Excute()
        {
            int    tokenLength = m_data.ReadInt32();
            string token       = m_data.ReadBytes(tokenLength).ToStringUnicode();

            if (ClientCenter.Instance.WaiteConnetctTcp.ContainsKey(token))
            {
                P2PTcpClient client = ClientCenter.Instance.WaiteConnetctTcp[token];
                ClientCenter.Instance.WaiteConnetctTcp.Remove(token);
                client.IsAuth        = m_tcpClient.IsAuth = true;
                client.ToClient      = m_tcpClient;
                m_tcpClient.ToClient = client;
                LogUtils.Debug($"命令:0x0211 已绑定内网穿透(2端)通道 {client.RemoteEndPoint}->{m_tcpClient.RemoteEndPoint}");
                //监听client
                AppCenter.Instance.StartNewTask(() => { Global_Func.ListenTcp <Packet_0x0212>(client); });
            }
            else
            {
                m_tcpClient.SafeClose();
                throw new Exception("绑定内网穿透(2端)通道失败,目标Tcp连接已断开");
            }
            return(true);
        }
Beispiel #20
0
        protected virtual void P2PBind_DirectConnect(P2PTcpClient p2pClient, string token)
        {
            if (m_tcpClient.P2PLocalPort > 0)
            {
                //B端
                int         port    = m_tcpClient.P2PLocalPort;
                PortMapItem destMap = appCenter.PortMapList.FirstOrDefault(t => t.LocalPort == port && string.IsNullOrEmpty(t.LocalAddress));

                P2PTcpClient portClient = null;

                EasyOp.Do(() =>
                {
                    if (destMap != null)
                    {
                        if (destMap.MapType == PortMapType.ip)
                        {
                            portClient = new P2PTcpClient(destMap.RemoteAddress, destMap.RemotePort);
                        }
                        else
                        {
                            portClient = new P2PTcpClient("127.0.0.1", port);
                        }
                    }
                    else
                    {
                        portClient = new P2PTcpClient("127.0.0.1", port);
                    }
                },
                          () =>
                {
                    portClient.IsAuth   = p2pClient.IsAuth = true;
                    portClient.ToClient = p2pClient;
                    p2pClient.ToClient  = portClient;
                    EasyOp.Do(() =>
                    {
                        if (Global_Func.BindTcp(p2pClient, portClient))
                        {
                            LogUtils.Debug($"命令:0x0201 P2P模式隧道,连接成功 token:{token}");
                        }
                        else
                        {
                            LogUtils.Debug($"命令:0x0201 P2P模式隧道,连接失败 token:{token}");
                        }
                    },
                              ex =>
                    {
                        LogUtils.Debug($"命令:0x0201 P2P模式隧道,连接失败 token:{token}:{Environment.NewLine}{ex}");
                    });
                },
                          ex =>
                {
                    LogUtils.Debug($"命令:0x0201 P2P模式隧道,连接目标端口失败 token:{token}:{Environment.NewLine}{ex}");
                    EasyOp.Do(() => { p2pClient.SafeClose(); });
                });
            }
            else
            {
                tcpCenter.WaiteConnetctTcp[token].Tcp = p2pClient;
                tcpCenter.WaiteConnetctTcp[token].PulseBlock();
            }
        }
        /// <summary>
        /// 端口映射监听端口的新tcp回调方法
        /// </summary>
        /// <param name="ar"></param>
        public void AcceptSocket_Server(IAsyncResult ar)
        {
            ListenSt    st       = (ListenSt)ar.AsyncState;
            TcpListener listener = st.listener;
            PortMapItem item     = st.item;
            Socket      socket   = null;

            try
            {
                //获取当前接入的tcp
                socket = listener.EndAcceptSocket(ar);
            }
            catch (Exception ex)
            {
                LogUtils.Error(ex.ToString());
                return;
            }

            EasyOp.Do(() =>
            {
                listener.BeginAcceptSocket(AcceptSocket_Server, st);
            }, () =>
            {
                EasyOp.Do(() =>
                {
                    if (tcpCenter.P2PServerTcp != null && tcpCenter.P2PServerTcp.Connected)
                    {
                        P2PTcpClient tcpClient = new P2PTcpClient(socket);
                        //加入待连接集合
                        P2PResult result = new P2PResult();
                        tcpCenter.WaiteConnetctTcp.Add(tcpClient.Token, result);
                        //tcpCenter.WaiteConnetctTcp.Add(tcpClient.Token, tcpClient);
                        //发送消息给服务端,开始内网穿透
                        Send_0x0201_Apply packet = new Send_0x0201_Apply(tcpClient.Token, item.RemoteAddress, item.RemotePort, item.P2PType);
                        LogUtils.Debug(string.Format("正在建立{0}隧道 token:{1} client:{2} port:{3}", item.P2PType == 0 ? "中转模式" : "P2P模式", tcpClient.Token, item.RemoteAddress, item.RemotePort));

                        byte[] dataAr = packet.PackData();
                        EasyOp.Do(() =>
                        {
                            tcpCenter.P2PServerTcp.BeginSend(dataAr);
                        }, () =>
                        {
                            //等待指定超时时间后,判断是否连接成功

                            Monitor.Enter(result.block);
                            if (Monitor.Wait(result.block, AppConfig.P2PTimeout))
                            {
                                if (tcpCenter.WaiteConnetctTcp[tcpClient.Token].IsError)
                                {
                                    LogUtils.Debug(tcpCenter.WaiteConnetctTcp[tcpClient.Token].ErrorMsg);
                                    tcpClient.SafeClose();
                                }
                                else
                                {
                                    P2PTcpClient destTcp = tcpCenter.WaiteConnetctTcp[tcpClient.Token].Tcp;
                                    tcpClient.IsAuth     = destTcp.IsAuth = true;
                                    destTcp.ToClient     = tcpClient;
                                    tcpClient.ToClient   = destTcp;
                                    if (item.P2PType == 0)
                                    {
                                        Global_Func.ListenTcp <Packet_0x0202>(tcpClient);
                                        LogUtils.Debug($"中转模式隧道,连接成功 token:{tcpClient.Token}");
                                    }
                                    else
                                    {
                                        if (Global_Func.BindTcp(tcpClient, destTcp))
                                        {
                                            LogUtils.Debug($"P2P模式隧道,连接成功 token:{tcpClient.Token}");
                                        }
                                        else
                                        {
                                            LogUtils.Debug($"P2P模式隧道,连接失败 token:{tcpClient.Token}");
                                            EasyOp.Do(tcpClient.SafeClose);
                                            EasyOp.Do(destTcp.SafeClose);
                                        }
                                    }
                                }
                            }
                            else
                            {
                                LogUtils.Debug($"建立隧道失败:token:{tcpClient.Token} {item.LocalPort}->{item.RemoteAddress}:{item.RemotePort} {AppConfig.P2PTimeout / 1000}秒无响应,已超时.");
                                EasyOp.Do(tcpClient.SafeClose);
                            }
                            tcpCenter.WaiteConnetctTcp.Remove(tcpClient.Token);
                            Monitor.Exit(result.block);
                            //if (tcpCenter.WaiteConnetctTcp.ContainsKey(tcpClient.Token))
                            //{
                            //    LogUtils.Debug($"建立隧道失败:token:{tcpClient.Token} {item.LocalPort}->{item.RemoteAddress}:{item.RemotePort} {AppConfig.P2PTimeout / 1000}秒无响应,已超时.");
                            //    tcpCenter.WaiteConnetctTcp[tcpClient.Token].tcp?.SafeClose();
                            //    tcpCenter.WaiteConnetctTcp.Remove(tcpClient.Token);
                            //}
                        }, ex =>
                        {
                            EasyOp.Do(tcpClient.SafeClose);
                            LogUtils.Debug($"建立隧道失败,无法连接服务器:token:{tcpClient.Token} {item.LocalPort}->{item.RemoteAddress}:{item.RemotePort}.");
                        });
                    }
                    else
                    {
                        LogUtils.Debug($"建立隧道失败:未连接到服务器!");
                        socket.Close();
                    }
                }, ex =>
                {
                    LogUtils.Debug("处理新tcp连接时发生错误:" + Environment.NewLine + ex.ToString());
                });
            }, ex =>
            {
                LogUtils.Error("监听端口发生错误:" + listener.LocalEndpoint.ToString() + Environment.NewLine + ex.ToString());
            });
        }
Beispiel #22
0
        protected virtual void TryBindP2PTcp()
        {
            string       ip        = BinaryUtils.ReadString(data);
            int          port      = BinaryUtils.ReadInt(data);
            string       token     = BinaryUtils.ReadString(data);
            int          bindPort  = Convert.ToInt32(m_tcpClient.Client.LocalEndPoint.ToString().Split(':')[1]);
            P2PTcpClient p2pClient = new P2PTcpClient();

            p2pClient.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
            EasyOp.Do(() =>
            {
                p2pClient.Client.Bind(new IPEndPoint(IPAddress.Any, bindPort));
            },
                      () =>
            {
                if (tcpCenter.WaiteConnetctTcp.ContainsKey(token))
                {
                    int p2pMode = tcpCenter.WaiteConnetctTcp[token].P2PType;
                    if ((p2pMode & 1) > 0)
                    {
                        LogUtils.Debug($"命令:0x0201 P2P模式隧道,开始端口复用打洞");
                        int tryCount = 3;
                        while (!p2pClient.Connected && tryCount > 0)
                        {
                            EasyOp.Do(() =>
                            {
                                p2pClient.Connect(ip, port);
                                p2pClient.UpdateEndPoint();
                            }, ex =>
                            {
                                LogUtils.Trace($"命令:0x0201 P2P模式隧道,端口打洞错误{ex}");
                            });
                            tryCount--;
                        }
                    }
                    if ((p2pMode & 2) > 0)
                    {
                        LogUtils.Debug($"命令:0x0201 P2P模式隧道,开始端口预测打洞");
                        p2pClient = TryRadomPort(ip, port);
                    }
                }

                if (p2pClient != null && p2pClient.Connected)
                {
                    LogUtils.Debug($"命令:0x0201 P2P模式隧道,打洞成功 port:{bindPort} token:{token}");
                    P2PBind_DirectConnect(p2pClient, token);
                }
                else
                {
                    EasyOp.Do(() => { p2pClient.SafeClose(); });
                    //如果是发起端,清空集合
                    if (m_tcpClient.P2PLocalPort <= 0)
                    {
                        if (tcpCenter.WaiteConnetctTcp.ContainsKey(token))
                        {
                            tcpCenter.WaiteConnetctTcp[token].ErrorMsg = $"命令:0x0201 P2P模式隧道,打洞失败 token:{token}";
                            tcpCenter.WaiteConnetctTcp[token].PulseBlock();
                        }
                    }
                    else
                    {
                        LogUtils.Debug($"命令:0x0201 P2P模式隧道,打洞失败 token:{token}");
                    }
                }
                EasyOp.Do(() => { m_tcpClient.SafeClose(); });
            },
                      ex =>
            {
                //如果是发起端,清空集合
                if (m_tcpClient.P2PLocalPort <= 0)
                {
                    if (tcpCenter.WaiteConnetctTcp.ContainsKey(token))
                    {
                        tcpCenter.WaiteConnetctTcp[token].ErrorMsg = $"命令:0x0201 P2P模式隧道,端口复用失败 token:{token}:{Environment.NewLine}{ex}";
                        tcpCenter.WaiteConnetctTcp[token].PulseBlock();
                    }
                }
                else
                {
                    LogUtils.Debug($"命令:0x0201 P2P模式隧道,端口复用失败 token:{token}:{Environment.NewLine}{ex}");
                }
            });
        }
Beispiel #23
0
        private void ListenPortMapPortWithServerName(PortMapItem item)
        {
            TcpListener listener = new TcpListener(IPAddress.Any, item.LocalPort);

            try
            {
                listener.Start();
            }
            catch (Exception ex)
            {
                LogUtils.Error($"【失败】端口映射:{item.LocalPort}->{item.RemoteAddress}:{item.RemotePort}{Environment.NewLine}{ex.ToString()}");
                return;
            }
            ListenerList.Add(listener);
            LogUtils.Info($"【成功】端口映射:{item.LocalPort}->{item.RemoteAddress}:{item.RemotePort}", false);
            AppCenter.Instance.StartNewTask(() =>
            {
                TcpManage tcpManage = null;
                if (item.RemotePort == 3389)
                {
                    tcpManage = new TcpManage(6);
                }
                while (true)
                {
                    Socket socket        = listener.AcceptSocket();
                    string remoteAddress = ((IPEndPoint)socket.RemoteEndPoint).Address.ToString();
                    if (tcpManage != null)
                    {
                        tcpManage.AddTcp(remoteAddress);
                        if (!tcpManage.IsAllowConnect(remoteAddress))
                        {
                            LogUtils.Info($"【安全策略】阻止内网穿透:{remoteAddress}->{item.LocalPort}->{item.RemoteAddress}:{item.RemotePort}", false);
                            socket.SafeClose();
                            continue;
                        }
                    }
                    LogUtils.Info($"开始内网穿透:{remoteAddress}->{item.LocalPort}->{item.RemoteAddress}:{item.RemotePort}", false);
                    P2PTcpClient tcpClient = new P2PTcpClient(socket);
                    AppCenter.Instance.StartNewTask(() =>
                    {
                        string token = tcpClient.Token;
                        //获取目标tcp
                        if (ClientCenter.Instance.TcpMap.ContainsKey(item.RemoteAddress) && ClientCenter.Instance.TcpMap[item.RemoteAddress].TcpClient.Connected)
                        {
                            //加入待连接集合
                            ClientCenter.Instance.WaiteConnetctTcp.Add(token, tcpClient);
                            //发送p2p申请
                            Models.Send.Send_0x0211 packet = new Models.Send.Send_0x0211(token, item.RemotePort, tcpClient.RemoteEndPoint);
                            ClientCenter.Instance.TcpMap[item.RemoteAddress].TcpClient.Client.Send(packet.PackData());
                            AppCenter.Instance.StartNewTask(() =>
                            {
                                Thread.Sleep(ConfigCenter.Instance.P2PTimeout);
                                //如果5秒后没有匹配成功,则关闭连接
                                if (ClientCenter.Instance.WaiteConnetctTcp.ContainsKey(token))
                                {
                                    LogUtils.Warning($"【失败】内网穿透:{ConfigCenter.Instance.P2PTimeout / 1000}秒无响应,已超时.");
                                    ClientCenter.Instance.WaiteConnetctTcp[token].SafeClose();
                                    ClientCenter.Instance.WaiteConnetctTcp.Remove(token);
                                }
                            });
                        }
                        else
                        {
                            LogUtils.Warning($"【失败】内网穿透:{item.LocalPort}->{item.RemoteAddress}:{item.RemotePort} 客户端不在线!");
                            tcpClient.SafeClose();
                        }
                    });
                }
            });
        }