public virtual void Start(ShadowsocksServerInfo info) { Verify.NotDisposed(this); Verify.Operation(Process is null || Process.HasExited, @"Process has started!"); Requires.NotNullAllowStructs(info.Plugin, nameof(info.Plugin)); LocalEndPoint = GetFreeLocalEndpoint(); Process = new Process { StartInfo = new ProcessStartInfo(info.Plugin) { UseShellExecute = false, CreateNoWindow = true, Environment = { [EnvRemoteHost] = info.Address, [EnvRemotePort] = info.Port.ToString(), [EnvLocalHost] = LocalEndPoint.Address.ToString(), [EnvLocalPort] = LocalEndPoint.Port.ToString(), [EnvPluginOpts] = info.PluginOpts } } }; Process.Start();
public ValueTask <IUdpClient> GetServerUdpAsync(string target, ushort targetPort) { ShadowsocksServerInfo info = GetInfo(); IUdpClient client = new ShadowsocksUdpClient(info); return(ValueTask.FromResult(client)); }
public async ValueTask <IPipeClient> GetServerAsync(string target, ushort targetPort) { if (target.Contains(@"baidu", StringComparison.OrdinalIgnoreCase)) { return(ConnectionRefusedTcpClient.Default); } if (target.Contains(@"ip.sb", StringComparison.OrdinalIgnoreCase) || IPAddress.TryParse(target, out _)) { return(await DirectConnectAsync(TimeSpan.FromSeconds(3))); } ShadowsocksServerInfo info = GetInfo(); if (string.IsNullOrEmpty(info.Plugin)) { return(await ConnectAsync(info, TimeSpan.FromSeconds(3))); } IPEndPoint pluginIpEndPoint = PluginServices.GetPluginService(info); ShadowsocksServerInfo newInfo = info with { Address = pluginIpEndPoint.Address.ToString(), Port = (ushort)pluginIpEndPoint.Port }; try { return(await ConnectAsync(newInfo, TimeSpan.FromSeconds(1))); } catch { PluginServices.RemoveService(info); pluginIpEndPoint = PluginServices.GetPluginService(info); newInfo = info with { Address = pluginIpEndPoint.Address.ToString(), Port = (ushort)pluginIpEndPoint.Port }; return(await ConnectAsync(newInfo, TimeSpan.FromSeconds(1))); } async ValueTask <IPipeClient> ConnectAsync(ShadowsocksServerInfo serverInfo, TimeSpan timeout) { IPipeClient client = new ShadowsocksTcpClient(serverInfo, target, targetPort); using CancellationTokenSource cts = new(timeout); await client.ConnectAsync(cts.Token); return(client); } async ValueTask <IPipeClient> DirectConnectAsync(TimeSpan timeout) { IPipeClient client = new DirectConnectTcpClient(target, targetPort); using CancellationTokenSource cts = new(timeout); await client.ConnectAsync(cts.Token); return(client); } }
public ShadowsocksUdpClient(ShadowsocksServerInfo serverInfo) { Requires.NotNull(serverInfo, nameof(serverInfo)); Requires.NotNullAllowStructs(serverInfo.Method, nameof(serverInfo)); Requires.NotNullAllowStructs(serverInfo.Password, nameof(serverInfo)); Requires.NotNullAllowStructs(serverInfo.Address, nameof(serverInfo)); _serverInfo = serverInfo; _client = new Socket(SocketType.Dgram, ProtocolType.Udp); _client.Connect(serverInfo.Address, serverInfo.Port); }
public static IDuplexPipe AsShadowsocksPipe( this IDuplexPipe pipe, ShadowsocksServerInfo serverInfo, string targetAddress, ushort targetPort, PipeOptions?readerOptions = null, PipeOptions?writerOptions = null) { PipeReader reader = pipe.Input.AsShadowsocksPipeReader(serverInfo, readerOptions); PipeWriter writer = pipe.Output.AsShadowsocksPipeWriter(serverInfo, writerOptions); writer.WriteShadowsocksHeader(targetAddress, targetPort); return(DefaultDuplexPipe.Create(reader, writer)); }
public ShadowsocksPipeReader( PipeReader reader, ShadowsocksServerInfo serverInfo, PipeOptions?pipeOptions = null) { Requires.NotNull(reader, nameof(reader)); Requires.NotNull(serverInfo, nameof(serverInfo)); Requires.NotNullAllowStructs(serverInfo.Method, nameof(serverInfo)); Requires.NotNullAllowStructs(serverInfo.Password, nameof(serverInfo)); IShadowsocksCrypto decryptor = ShadowsocksCrypto.Create(serverInfo.Method, serverInfo.Password); InternalReader = reader; _pipe = new Pipe(pipeOptions ?? PipeOptions.Default); _cancellationTokenSource = new CancellationTokenSource(); WrapAsync(decryptor, _cancellationTokenSource.Token).Forget(); }
public void Sip002UriSchemeTest(string uri, string?remark, string?address, ushort port, string?password, string?method, string?plugin, string?pluginOpts) { ShadowsocksServerInfo serverInfo = new() { Remarks = remark, Address = address, Port = port, Password = password, Method = method, Plugin = plugin, PluginOpts = pluginOpts }; Assert.AreEqual(uri, serverInfo.ToSip002UriSchemeString()); Assert.IsTrue(ShadowsocksServerInfo.TryParse(uri, out ShadowsocksServerInfo? newInfo)); newInfo.Id = serverInfo.Id; Assert.AreEqual(serverInfo, newInfo); } }
public ShadowsocksTcpClient(ShadowsocksServerInfo serverInfo, string targetAddress, ushort targetPort) { _serverInfo = serverInfo; _targetAddress = targetAddress; _targetPort = targetPort; }