Exemplo n.º 1
0
        internal async Task AcceptConnectorAndWorkAsync(Socket clientSock, CommandMessage connmsg)
        {
            bool supportEncrypt = false;

            byte[] clientKeyIV;
            try
            {
                this.Server.ConnectorLicense.DescriptSourceKey(Convert.FromBase64String(connmsg.Args[2]), Convert.FromBase64String(connmsg.Args[3]), out clientKeyIV);
            }
            catch (Exception x)
            {
                OnError(x);
                var failedmsg = new CommandMessage("ConnectFailed", "InvalidSecureKey");
                await clientSock.SendAsync(failedmsg.Pack(), SocketFlags.None);

                return;
            }

            if (connmsg.Args[4] == "0")
            {
                supportEncrypt = false;
            }


            var resmsg = new CommandMessage("ConnectOK", "OK", "Connected");
            await clientSock.SendAsync(resmsg.Pack(), SocketFlags.None);

            Stream _sread, _swrite;

            if (supportEncrypt)
            {
                Server.ConnectorLicense.OverrideStream(clientSock.CreateStream(), clientKeyIV, out _sread, out _swrite);
            }
            else
            {
                _sread = _swrite = clientSock.CreateStream();
            }

            string mode = connmsg.Args[5];

            if (mode == "USB")            //use server bandwidth
            {
                Socket localsock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                string ip        = Server.ServerBind;
                if (ip == "0.0.0.0")
                {
                    ip = "127.0.0.1";
                }
                localsock.InitTcp();
                await localsock.ConnectAsync(ip, Server.ServerPort);

                TcpMapConnectorSession session = new TcpMapConnectorSession(new SimpleSocketStream(localsock));
                await session.DirectWorkAsync(_sread, _swrite);
            }
            else
            {
                throw new NotImplementedException();
            }
        }
Exemplo n.º 2
0
        async Task ProcessSocketAsync(Socket tcpSocket)
        {
            Socket serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

            serverSocket.InitTcp();
            await serverSocket.ConnectAsync(Connector.ServerHost, 6022);

            bool supportEncrypt = false;

            byte[] clientKeyIV;

            CommandMessage connmsg = new CommandMessage();

            connmsg.Name = "ConnectorConnect";
            List <string> arglist = new List <string>();

            arglist.Add(this.Connector.License.Key);
            arglist.Add(this.Connector.ServerPort.ToString());
            byte[] encryptedKeyIV, sourceHash;
            Connector.License.GenerateSecureKeyAndHash(out clientKeyIV, out encryptedKeyIV, out sourceHash);
            arglist.Add(Convert.ToBase64String(encryptedKeyIV));
            arglist.Add(Convert.ToBase64String(sourceHash));
            arglist.Add(supportEncrypt ? "1" : "0");
            arglist.Add("USB");
            connmsg.Args = arglist.ToArray();

            await serverSocket.SendAsync(connmsg.Pack(), SocketFlags.None);

            connmsg = await CommandMessage.ReadFromSocketAsync(serverSocket);

            if (connmsg == null)
            {
                LogMessage("Warning:ConnectorWorker : remote closed connection.");
                return;
            }

            LogMessage("Warning:connmsg : " + connmsg);

            if (connmsg.Name != "ConnectOK")
            {
                return;
            }


            Stream _sread, _swrite;

            if (supportEncrypt)
            {
                Connector.License.OverrideStream(serverSocket.CreateStream(), clientKeyIV, out _sread, out _swrite);
            }
            else
            {
                _sread = _swrite = serverSocket.CreateStream();
            }

            TcpMapConnectorSession session = new TcpMapConnectorSession(new SimpleSocketStream(tcpSocket));
            await session.DirectWorkAsync(_sread, _swrite);
        }
Exemplo n.º 3
0
        private async Task HandleStreamAsync(Stream stream, IPEndPoint remote)
        {
            _worker.LogMessage("UDP Session Start : " + _udp.Client.LocalEndPoint + " , " + remote);
            try
            {
                using Socket localsock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                localsock.InitTcp();
                await localsock.ConnectAsync(_worker.Client.ClientHost, _worker.Client.ClientPort);

                TcpMapConnectorSession session = new TcpMapConnectorSession(new SimpleSocketStream(localsock));
                await session.DirectWorkAsync(stream, stream);
            }
            catch (Exception x)
            {
                _worker.OnError(x);
            }
            finally
            {
                stream.Close();
            }
        }
Exemplo n.º 4
0
        private async Task ProcessSocketAsync(Socket tcpSocket)
        {
TryAgain:
            string connmode = null;

            if (this.Connector.UseRouterClientPort && DateTime.Now > this.stopUseRouterClientPortUntil)
            {
                connmode = "RCP";
            }
            else if (this.Connector.UseUDPPunching && DateTime.Now > this.stopUseRouterClientPortUntil)
            {
                connmode = "UDP";
            }
            else if (this.Connector.UseServerBandwidth)
            {
                connmode = "USB";
            }
            else
            {
                //TODO:  try ..
                connmode = this.Connector.UseUDPPunching
                    ? "UDP"
                    : this.Connector.UseRouterClientPort ? "RCP" : throw new Exception("No connection mode.");
            }

            Task <KeyValuePair <string, UDPClientListener> > task2 = null;

            if (connmode == "UDP")
            {
                //TODO: shall cache the UDPClientListener ...
                task2 = Task.Run(this.GetUdpClientAsync);
            }

            Socket serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

            serverSocket.InitTcp();
            await serverSocket.ConnectAsync(this.Connector.ServerHost, 6022);

            string            connArgument = null;
            UDPClientListener udp          = null;

            if (task2 != null)
            {
                try
                {
                    var kvp = await task2;
                    connArgument = kvp.Key;
                    udp          = kvp.Value;
                }
                catch (Exception x)
                {
                    this.OnError(x);
                    this.LogMessage("UDP Failed , switch ...");
                    connmode = this.Connector.UseServerBandwidth ? "USB" : throw new Exception(x.Message, x);
                }
            }

            bool supportEncrypt = this.Connector.UseEncrypt;

            CommandMessage connmsg = new CommandMessage
            {
                Name = "ConnectorConnect"
            };
            List <string> arglist = new List <string>
            {
                this.Connector.License.Key,
                this.Connector.ServerPort.ToString()
            };

            this.Connector.License.GenerateSecureKeyAndHash(out byte[] clientKeyIV, out byte[] encryptedKeyIV, out byte[] sourceHash);
            arglist.Add(Convert.ToBase64String(encryptedKeyIV));
            arglist.Add(Convert.ToBase64String(sourceHash));
            arglist.Add(supportEncrypt ? "1" : "0");
            arglist.Add(connmode);
            arglist.Add(connArgument);
            connmsg.Args = arglist.ToArray();

            await serverSocket.SendAsync(connmsg.Pack(), SocketFlags.None);

            connmsg = await CommandMessage.ReadFromSocketAsync(serverSocket);

            if (connmsg == null)
            {
                this.LogMessage("Warning:ConnectorWorker : remote closed connection.");
                return;
            }

            //LogMessage("Warning:connmsg : " + connmsg);

            if (connmsg.Name != "ConnectOK")
            {
                return;
            }

            //TODO: add to session list

            if (supportEncrypt && connmsg.Args[1] == "0")
            {
                supportEncrypt = false; this.LogMessage("Warning:server don't support encryption : " + this.Connector.ServerHost);
            }

            Stream _sread, _swrite;

            if (connmode == "RCP")
            {
                serverSocket.CloseSocket();

                string ip   = connmsg.Args[2];
                int    port = int.Parse(connmsg.Args[3]);
                if (port < 1)
                {
                    this.LogMessage("Error:Invalid configuration , remote-client-side don't provide RouterClientPort , stop use RCP for 1min");
                    this.stopUseRouterClientPortUntil = DateTime.Now.AddSeconds(60);
                    goto TryAgain;//TODO: reuse the serverSocket and switch to another mode
                }

                this.LogMessage("Warning:" + tcpSocket.LocalEndPoint + " forward to " + ip + ":" + port);
                await tcpSocket.ForwardToAndWorkAsync(ip, port);

                return;
            }

            if (connmode == "UDP")
            {
                this.LogMessage("MY UDP..." + connArgument + " REMOTE..." + connmsg.Args[2]);

                string   mynat = connArgument;
                string[] pair  = connmsg.Args[2].Split(':');

                serverSocket.CloseSocket();

                try
                {
                    UDPClientStream stream = await UDPClientStream.ConnectAsync(udp, pair[0], int.Parse(pair[1]), TimeSpan.FromSeconds(6));

                    _sread  = stream;
                    _swrite = stream;

                    this.LogMessage("UDP Connected #" + stream.SessionId + " " + connArgument + " .. " + connmsg.Args[2]);
                }
                catch (Exception x)
                {
                    this.LogMessage("UDP ERROR " + connArgument + " .. " + connmsg.Args[2] + " " + x.Message);
                    throw;
                }
            }
            else
            {
                if (supportEncrypt)
                {
                    this.Connector.License.OverrideStream(serverSocket.CreateStream(), clientKeyIV, out _sread, out _swrite);
                }
                else
                {
                    _sread = _swrite = serverSocket.CreateStream();
                }
            }

            TcpMapConnectorSession session = new TcpMapConnectorSession(new SimpleSocketStream(tcpSocket));
            await session.DirectWorkAsync(_sread, _swrite);
        }
Exemplo n.º 5
0
        internal async Task AcceptConnectorAndWorkAsync(Socket clientSock, CommandMessage connmsg)
        {
            bool supportEncrypt = _worker.Server.UseEncrypt;

            if (connmsg.Args[4] == "0")
            {
                supportEncrypt = false;
            }

            byte[] clientKeyIV;
            try
            {
                _worker.Server.ConnectorLicense.DescriptSourceKey(Convert.FromBase64String(connmsg.Args[2]), Convert.FromBase64String(connmsg.Args[3]), out clientKeyIV);
            }
            catch (Exception x)
            {
                _worker.OnError(x);
                var failedmsg = new CommandMessage("ConnectFailed", "InvalidSecureKey");
                await clientSock.SendAsync(failedmsg.Pack(), SocketFlags.None);

                return;
            }

            TcpMapServerClient sclient = _worker.FindClient();

            if (sclient == null)
            {
                var failedmsg = new CommandMessage("ConnectFailed", "NoClient");
                await clientSock.SendAsync(failedmsg.Pack(), SocketFlags.None);

                return;
            }

            string mode         = connmsg.Args[5];
            string connArgument = connmsg.Args[6];

            if (mode == "USB")            //use server bandwidth
            {
                var resmsg = new CommandMessage("ConnectOK", "ConnectOK", supportEncrypt ? "1" : "0");
                await clientSock.SendAsync(resmsg.Pack(), SocketFlags.None);

                Stream _sread, _swrite;
                if (supportEncrypt)
                {
                    _worker.Server.ConnectorLicense.OverrideStream(clientSock.CreateStream(), clientKeyIV, out _sread, out _swrite);
                }
                else
                {
                    _sread = _swrite = clientSock.CreateStream();
                }

                using Socket localsock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                string ip = _worker.Server.ServerBind;
                if (ip == "0.0.0.0")
                {
                    ip = "127.0.0.1";
                }
                localsock.InitTcp();
                await localsock.ConnectAsync(ip, _worker.Server.ServerPort);

                TcpMapConnectorSession session = new TcpMapConnectorSession(new SimpleSocketStream(localsock));
                await session.DirectWorkAsync(_sread, _swrite);
            }
            else if (mode == "UDP")
            {
                if (_udpcache == null)
                {
                    lock (typeof(TcpMapServerConnector))
                    {
                        if (_udpcache == null)
                        {
                            var opt = new MemoryCacheOptions();
                            Microsoft.Extensions.Options.IOptions <MemoryCacheOptions> iopt = Microsoft.Extensions.Options.Options.Create(opt);
                            _udpcache = new MemoryCache(iopt);
                        }
                    }
                }

                UdpInfoItem natinfo;
                string      key = connArgument + ":" + sclient.SessionId;
                if (!_udpcache.TryGetValue(key, out natinfo) || natinfo.HasExpired())
                {
                    var udpmsg = await sclient.CreateUDPNatAsync(connArgument);

                    string[] pair = udpmsg.Args[1].Split(':');
                    string   addr = pair[0];
                    int      port = int.Parse(pair[1]);
                    natinfo = new UdpInfoItem(addr + ":" + port);
                    _udpcache.Set(key, natinfo);
                }



                var resmsg = new CommandMessage("ConnectOK", "ConnectOK", supportEncrypt ? "1" : "0", natinfo.NatInfo);
                await clientSock.SendAsync(resmsg.Pack(), SocketFlags.None);

                resmsg = await CommandMessage.ReadFromSocketAsync(clientSock);

                if (resmsg == null)
                {
                    return;
                }
                throw new NotImplementedException("work for " + resmsg);
            }
            else if (mode == "RCP")
            {
                var resmsg = new CommandMessage("ConnectOK", "ConnectOK", supportEncrypt ? "1" : "0"
                                                , ((IPEndPoint)sclient._socket.RemoteEndPoint).Address.ToString(), sclient.OptionRouterClientPort.ToString());
                await clientSock.SendAsync(resmsg.Pack(), SocketFlags.None);
            }
            else
            {
                throw new NotImplementedException();
            }
        }