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(); } }
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); }
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(); } }
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); }
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(); } }